Protobuf : C++ string with null characters inside - c++

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.

Related

omitting the null string terminator in c++ string

In my little project, I am trying to hash some bitmaps and the bitmaps are like: "BMP1 /0 bitmap data". I am using a md5 hash library that I found on the internet and it works as simple as:
std::string md5(const std::string);
The problem is, since I have a string terminator in the middle of the memory, if I try to make a string from this memory, I can have only the first part and not the bitmap data. So, my question is, can I not finish the string here and take the whole data into it. Thanks in advance.
If you take a look at the constructors that std::string provides, you'll find that among the many constructors, besides the constructor that takes a null terminated string as an argument (5), there is a constructor that takes pointer to a character string, and a count of characters (4). The description mentions specifically that the pointed string may contain null characters. This means that the null characers do not terminate the string.

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.

Qt string termination

I'm trying to parse a payload in qt.
The payload is a const u_char *, and I also have its length. The payload may contain null characters.
I would like to do various operations with the payload, such as finding if it contains a given string, using regex on it, etc, which is why using a QString seemed easier to manipulate it.
So I tried QString s((const char*) payload); but this constructor doesn't allow null characters within the string.
Hence my questions :
Is it possible to create a QString that contains a null character ?
Should I use another object instead of a QString, and if so, which one (one that would still allow to search within it and match it against a regex ?
Thanks
If you want to use QRegExp (or QRegularExpression in Qt5), you need to use a QString. To construct a QString from raw bytes, you need to specify the character encoding to do so. If your payload carries UTF-8 text, use QString::fromUtf8 which also takes a size parameter. Then, the data may also contain a null character which will be part of the string instead of terminate it:
QString str = QString::fromUtf8(data, length);
If you want to use regular expressions on binary data, don't use QRegExp. Use boost::regex or std::regex instead, they handle binary data well. They can operate on std::string (but are generic), which can be constructed also with a data-and-length constructor similar to the above code:
string str { data, length };
I would recommend using a std::stringstream, this object can contain null characters and do a number of different operations.
http://www.cplusplus.com/reference/sstream/stringstream/stringstream/

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.

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

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);