Arduino c++ First letter of string missing - c++

I'm receiving a string from one serial port and repeating to a second serial port. The following code works, but the first letter (number 4 in this case) of the string is missing.
while(Serial1.available()){
MyString = Serial1.readString();
}
client.print(MyString);
The end result is "192A4BF,0,3.999023" when it should be "4192A4BF,0,3.999023"

You're reading from Serial1 in a loop, overwriting all strings that you receive except for the last one. What likely happens is that you first read — and discard — 4 and then read — and print — the rest.
Moving the print into the loop should fix this:
while(Serial1.available()){
MyString = Serial1.readString();
client.print(MyString);
}

Related

in c++ program after pressing enter , "cin" will feed all Variables

I have a program that takes two numbers and shows them on the screen.
However, when I hit "enter" after I input the first number, my program shows the answers before letting me input the second number.
Why does this happen?
int main()
{
int n1;
float n2;
cin>>n1;
cin>>n2;
cout<<"int n:"<<n1<<endl<<"float n:"<<n2;
return 0;
}
I wanna input 0.25 and 35 but when I write 0.25 and hit enter suddenly shows the answer "int: n:0 float n:0.25" it doesn't let me write second num. my os is Win10 and this program compiled with DevCpp
It works when both variables are ints.
There is no difference between cin>>n1; cin>>n2; and cin >> n1 >>n2. Enter key only serves as signal to sychronize input buffer and stream buffer. cin doesn't input per line, it parses buffer when there is available volume of data. If parse incomplete, it waits. If parse can't be done, it stops and state bit changes. To continue parsing you have either ignore or clear part or whole buffer content.
Something wrong was entered in first line, causing cin to go into bad() state. Edge case might happen if you're running program through a remote terminal, some incorrect character could slip in, e.g. ^M generated by new line from Windows would break cin stream on Linux. That's also case if you input from a file which was saved on different platform. On Windows line ends consist of two characters, #10 and #13. On linux steams expect only #13 as a new line and buffer flush signal, #10 is an unexpected character.
Edit (after OP gave information about input data):
"0.25" would be parsed as "0" and ".25", that expected and documented stream behavior. Parsing for n1 had stopped as soon as stream encountered character which doesn't fit int pattern, which could be space, end of line, alphabetic or punctuation. Period considered a punctuation in this case
Then it tries to get a float from stream input and buffer contains ".25". It's a legal float notation and it gets assigned to n2.
When you have both "int", you cannot get second value at all with same input, it always will be 0, because cin locks up in bad state, i.e. method its istream::good() returns false. You have to check state of stream after reading variables. Any further formatted reading that wouldn't be able to parse .25 wouldn't advance stream past that point.
If you want to read from stream exclusively line by line, you have to use istream::getline() method to get the string. There is also method get which can acquire content of stream and ignore which allows to discard part of stream.

Reading two line continuously using getline function in c++

I was learning how to read strings with getline function.
I know that getline function read string as far as we don't hit enter or the size value in the getline parameter go cross. As far as I tried getline function to read one line of string I had not faced any problem.
But when I was trying to read two line of string one after another in two different char array i got the output that was not expected to me.
To understand my question follow bellow lines
#include <iostream>
using namespace std;
int main()
{
char line1[10];
char line2[10];
cin.getline(line1,7);
cin.getline(line2,7);
cout << "\nline1 =" << line1 <<endl;
cout << "line2 =" << line2 <<endl;
}
When I ran the above program it ask me for input then I gave orange as first input and hit the enter button.
Next it ask me to give the second input .then i gave banana and hit the enter button .in this case it produce the result i expected .But if enter oranges for the first input it does not wait for me to enter the second input.
As a result line1 store orange but line2 remains blank.
Now my question is that there is no wrong with line1 storing orange. But I don't understand why the line2 remains blank should not it contain the data that remains after line1 take input I mean should not line2 contain s as value.
Because orange is a 6 digit word so getline will stores the first six digit after then a null character will be added as I set the size of geline 7.
Then other remaing data will be assigend in the next call of getline function.So should not s stored in line2 as after s a new_line character is read for the first time.
Why will be line2 remain blank and why the screen doesn't stop for taking input after giving the first input?
std::istream::getline is being overloaded with data.
According to cppreference,
Behaves as UnformattedInputFunction. After constructing and checking the sentry object, extracts characters from *this and stores them in successive locations of the array whose first element is pointed to by s, until any of the following occurs (tested in the order shown):
end of file condition occurs in the input sequence (in which case setstate(eofbit) is executed)
the next available character c is the delimiter, as determined by Traits::eq(c, delim). The delimiter is extracted (unlike basic_istream::get()) and counted towards gcount(), but is not stored.
count-1 characters have been extracted (in which case setstate(failbit) is executed).
Emphasis mine.
cin.getline(line1,7);
// ^ This is count
can read only 6 characters with the 7th reserved for the null terminator. "oranges" is seven characters, and this places cin in a non-readable error state that must be cleared before reading can be continued. Reading of the second line
cin.getline(line2,7);
instantly fails and no data is read.
The obvious solution is
cin.getline(line1, sizeof(line1));
to take advantage of the whole array. But...
Any IO transaction should be tested for success, so
if (cin.getline(line1, sizeof(line1)))
{
// continue gathering
}
else
{
// handle error
}
is a better option.
Better still would be to use std::getline and std::string to almost eliminate the size constraints.

C++ multiple cin.get()

Could seem an old question, but the problem here isn't the use of TWO cin.get(), but of more than two! if I write (in DEV C++)
I get just one input request (s) and then end program. Now, I expected having at least two request of cin, because I expected:
char s[50];
char t[100];
char r[100];
char f[100];
cin.get(s,49);
cin.get(t,99);
cin.get(r,99);
cin.get(f,99);
I expeted at least 2 input request, because:
first cin: buffer empty,I insert the string s and \n
second cin: I have in buffer \n still, then t=\n without input request
third cin: buffer empty, I insert the string r and \n
fourth cin: I have in buffer \n still, then f=\n without input request
But I have just the input request for s string!
why have I just one input request?the buffer didn't clean with second cin.get, letting third cin.get work properly? Thanks
t does NOT equal '\n'. It's empty. .get(char*,int) will never remove the '\n' from the buffer.
Worse, the attempt to read to t will set cin to a fail state since nothing could be read, which will cause all subsequent reads of any sort from cin to fail immediately without even trying until you .clear() the fail state.
This is surprising behavior, but you seem to have already guessed at most of it as per your last sentence in the question, so, Good Job! You're learning!
http://en.cppreference.com/w/cpp/io/basic_istream/get

Capturing serial input in string/char array

I have a software serial link between an Arduino Uno and a TC35 GSM Module to send and receive SMS messages. Sending SMS'/calls is not a problem as it is a matter of sending the appropriate AT command to the GSM module. However I wish to use the AT+CMGR=1 command (which checks the first SMS stored on the SIM card) to check if there is any messages and store the message as a char array so that I can then check if the SMS contains the word 'on' or 'off' to activate a LED.
The AT+CMGR=1 command should return the following:
AT+CMGR=1
+CMGR: "REC READ","+3538xxxxxxxx",,"13/03/23,14:29:37+00"
Set
OK
But in the method below when I print 'data' it just returns:
Message contains:
AT
Any pointers would be much appreciated.
void checkMessage() {
gsmSerial.println("AT+CMGR=1"); //Reads the first SMS
for (x=0;x < 255;x++){
data[x]='\0';
}
x=0;
do{
while(gsmSerial.available()==0);
data[x]=gsmSerial.read();
x++;
if(data[x-1]==0x0D&&data[x-2]=='"'){
x=0;
}
}while(!(data[x-1]=='K'&&data[x-2]=='O'));
data[x-3]='\0'; //finish the string before the OK
Serial.println("\r\nMessage contains: \r");
Serial.println(data); //shows the message
delay(1000);
}
I don't understand your intent of doing this:
if(data[x-1]==0x0D&&data[x-2]=='"'){
x=0;
}
It appears you're discarding your data and reading new data whenever you hit a line containing a trailing quote and newline. So the response to the command of interest is being discarded. I haven't tested it, but I think it would work if you deleted those three lines.
I should also mention that [x-1] and [x-2] are referencing memory prior to the data buffer. That's a very bad practice that can and will cause undefined behavior. You should only check the index minus some value when the result of that computation will be a positive value. A negative array index will access memory prior to the start of the array.

getline() omitting the first letter of my output string

Hi i am a newbie in c++ and was doing some basic exercise. my code takes user input and feeds them in an array. Now i am using getline() to get the input string. my code is as follows:
cin.getline(cb[0].name, 200).get(); // Cadburry
cin.getline(cb[1].name, 200).get(); // Snickers
cin.getline(cb[2].name, 200); // Milky Bar
But when i output the strings, the first getline() seems to be fine but the other two are omitting the first letter of the string. So the output in this case is :
Cadburry
nickers
ilky Bar
can anyone please tell me why is it so?
The get() calls are consuming the S and the M, remove those and it will work. getline() already consumes the \n