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/
Related
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.
Why do they have a System::String and a std::string in c++?
I couldn't find anything about this, except some topics about converting the one to another.
I noticed this when I want to put information of a textbox into a std::string variable. so I had to do some odd converting to get this.
Why do they have these 2 different strings when they actually do the same for coding? (holding a string value).
std::string is a class template from the c++ standard library that stores and manipulates strings. The data in std::string is basically a sequence of bytes, i.e. it doesn't have en encoding. std::string supports the most basic set of operations that you would expect from a string, namely it gives you methods for substring search and replace.
System::string is a class from Microsoft's .Net framework. It represents text as a series of Unicode characters, and has some more specialized methods like StartsWith, EndsWith, Split, Trim, ans so on.
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.
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.
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.