c++ char arrays, use in cin.getline() - c++

I have the following code:
char myText[256];
cin.getline(myText,256);
Why exactly do I have to pass a character array to cin.getline() and not a string?
I have read that in general it is better to use strings than character arrays. Should I then convert a character array to a string after retrieving input with cin.getline(), if that is possible?

You are using the member method of istream. In this case cin. This function's details can be found here :
http://en.cppreference.com/w/cpp/io/basic_istream/getline
However you could use std::getline
Which uses a string instead of a char array. It's easier to use string since they know their sizes, they auto grow etc. and you don't have to worry about the null terminating character and so on. Also it is possible to convert a char array to a string by using the appropriate string contructor.

That's an unfortunate historical artifact, I believe.
You can however, use the std::getline free function instead.
std::string myText;
std::getline(std::cin,myText);

Related

The best method for filling char array (gets vs cin.getline)

I'm using C ++ 11. I'm wondering if there are any advantages to using cin.getline () compared to gets ().
I need to fill a char array.
Also, should I use fgets or getline for files?
I'm wondering if there are any advantages to using cin.getline () compared to gets ().
I am assuming you really mean gets, not fgets.
Yes, there definitely is. gets is known to be a security problem. cin.getline() does not suffer from that problem.
It's worth comparing fgets and cin.getline.
The only difference that I see is that fgets will include the newline character in the output while cin.getline won't.
Most of the time, the newline character is ignored by application code. Hence, it is better to use cin.getline() or istream::getline() in general. If presence of the newline character in the output is important to you for some reason, you should use fgets.
Another reason to prefer istream::getline is that you can specify a character for the delimiter. If you need to parse a comma separated values (CSV) file, you can use:
std::ifstream fstr("some file name.csv");
fstr.getline(data, data_size, ',');
Of course.
First of all gets doesn't check of length of the input - so if the input if longer than char array, you are getting an overflow.
On the other hand cin.getline allows to specify the size of stream.
Anyway, the consensus among C++ programmers is that you should avoid raw arrays anyway.

Read an ifstream word for word into char*

Just trying a programming test for fun. It stipulates that I should read each word of a file, one by one.
It hints that I might want to use ifstream, but won't let me use std::string, so it looks like I have to use char*
In C I would read line by line & use strok() as I have multiple delimiters (white-space, quotes, brackets, etc).
What the most C++ way to do this - get the words one by one - without using std::string ?
First you must make sure that you have memory allocated for your string (this part would be handled automatically by std::string). Then just use the normal input operator >>, as it will separate on whitespace.
Don't forget to free the memory you allocate (also handled automatically by std::string).
Lesson to be learned: Use char pointers for exercises like these, otherwise use std::string.
Just read the file into a std::string and then use std::string::c_str ( ) to retrive the nul-terminated C-style string from std::string object.

Protobuf : C++ string with null characters inside

I am dealing with a buffer in memory which is being read as protobuf. I need to deserialize it. The content of this protobuf contains a string which may or may not have null character inside the string. For example, the string could be something like this : "name\0first". If I have the input like this, the string that I can deserialize always looks like "name" since the string class drops the part after null character.
How can I access the complete string in this case? String length function obviously do not help in this case.
First, you need to construct the string appropriately. You cannot construct it using the constructors that are looking for NULL terminators, which is what string(const char *) is looking for.
You have to use the constructor that takes a pointer and length.
string s("name\0first", 10);
If you have already constructed a string, and want to append data that has embedded NULLs, you can use the append() method.
string s;
s.append("name\0first", 10);
Use the constructor that takes the number of characters std::string s(buffer, nChars). It is the fifth from this reference.

converting a string to a c string

m working on some homework but don't even know where to start on this one. If you could can you throw me in the right direction. This is what i'm suppose to do
Write your own version of the str_c function that takes a C++ string as an argument (with the parameter set as a constant reference variable) and returns a pointer to the equivalent C-string. Be sure to test it with an appropriate driver.
There are different possibilities to write such a function.
First, take a look at the C++ reference for std::string, which is the starting point for your problem.
In the Iterator section on that page, you might find some methods which can help you to get the string character by character.
It can also help to read the documentation for the std::string::c_str method, you'd like to imitate: string::c_string. It's important to understand, how the system works with normal C-strings (char*):
Due to the fact, that a C-string has now length- or size-attribute, a trick is used to determine the end of the string: The last character in the string has to be a '\0'.
Make sure you understand, that a char* string can also be seen as array of characters (char[]). This might help you, when understanding and solving your problem.
as we know, C-string is null-terminated array of char. you can put char by char from std::string to an array of char, and then closed with '\0'. and remember a pointer to a char (char*) is also representation of array of char. you can use this concept

Split and Assign char

I am new to C++ and Arduino.
I have 3 variable of type char
char receivePayload[31];
char devID;
char switchState;
the data in receivePayload woudl be some like "01:01" or "01:00". Here the first part before colon is device ID and second part is switchState.
Can you please help me and explain how I can split the 2. I did read about strtok but was unable to understand.
The desired output would be like
devID would have 01 stored and
switchState would have 01 or 00 stored.
Also if I can convert it into integer.
Thanks a ton.
As for your problem, there are multiple solutions to it: One is using std::getline as tokenizer. Another is using std::string::find and std::string::substr. Yet another solution is to use the old C function strtok.
The above solutions all give you strings, so either you have to make devId and switchState strings as well, or use e.g. std::stoi to convert the strings to integers.
Apparently the Arduino platform have neither of the functionality listed above, which mean you have to tokenize the string yourself. This is, however, very simple: Find the separator (the ':' character), copy from the beginning to (but not including) the separator into a temporary string and convert it to an integer with e.g. std::strtol. Then copy from (but not including) the separator into the temporary string and convert that value to an integer.
If you don't even have std::strtol then use std::atoi.
Since this is Arduino, you should probably use the String class since it handles a lot of the annoying stuff for you like conversion to int without having to explicitly link against glibc.
You could split the string like so:
String receivedPayload("01:10");
String devId = receivedPayload.substring(0, receivedPayload.indexOf(':'));
String switchState = receivedPayload.substring(receivedPayload.indexOf(':'));
Converting them into an integer would involve just using toInt on the string objects.
If you didn't need to convert into an integer, it would have been easier to tokenise the string yourself by using a for loop and checking if the character is equal to ':' since the string is so short.