i'm using std::string.find() to search a buffer for a static header
if this buffer contains \0 chars will this cause a problem... say it thinks thats the end of the string?
[edit]
nm it does cause problems
This is a discussion on quick q: std::string within the C++ Programming forums, part of the General Programming Boards category; i'm using std::string.find() to search a buffer for a static header if this buffer contains
i'm using std::string.find() to search a buffer for a static header
if this buffer contains \0 chars will this cause a problem... say it thinks thats the end of the string?
[edit]
nm it does cause problems
Last edited by Nor; 07-17-2003 at 09:34 AM.
Try to help all less knowledgeable than yourself, within
the limits provided by time, complexity and tolerance.
- Nor
Yes and no. std::string can contain \0 characters internally without any problems or truncation, but C-style strings can't, so conversions between C-style and std::string often truncate if there are \0 characters internally. E.g.:
produces:Code:#include <iostream> #include <string> int main(){ std::string s1("Test_Test"); s1[4] = '\0'; std::string s2("Test\0Test"); std::string s3("Test\0Test",9); std::cout << "S1.Length : " << s1.length() << std::endl; std::cout << "S1 : " << s1 << std::endl; std::cout << "S1.CString: " << s1.c_str() << std::endl; std::cout << "S2.Length : " << s2.length() << std::endl; std::cout << "S2 : " << s2 << std::endl; std::cout << "S2.CString: " << s2.c_str() << std::endl; std::cout << "S3.Length : " << s3.length() << std::endl; std::cout << "S3 : " << s3 << std::endl; std::cout << "S3.CString: " << s3.c_str() << std::endl; }
You note S1 and S3 are 9 characters long (and do NOT end at the \0 in the middle), but S2 is only 4 characters long, because this string literal:Code:S1.Length : 9 S1 : Test Test S1.CString: Test S2.Length : 4 S2 : Test S2.CString: Test S3.Length : 9 S3 : Test Test S3.CString: Test
std::string s2("Test\0Test");
is only *4* characters long. If you think about how that constructor works, the compiler puts a string literal "Test\0Test\0" somewhere in a data segment. Then the constructor is called with a pointer to the first character. It isn't passed the length, so it can do only one thing -- read until the first \0. For S3, the length is given, so the \0 is put in the middle.
Note also that, as you would expect, c_str() truncates the longer strings. A c-string ends with the first \0, so it's no surprise it works as it does.
Just to wrap up cat's excelent post, this means that if you want to find "test\0test" you have to either create a std::string that contains the string with the embeded null that you are looking for or use a form of find that allows you to specify a length.
most(if not all, I am lazy) of std::string's methods that accept char*'s as args also have variants that will accept a size_type to specify the length of the string.Code:str.find("test\0test",0,9); or str.find(std::string("test\0test",9));
i'm laze and just want the search.
i just setup a quick loop to ensure that no nulls are present in the buf before i assign it to the string.
Try to help all less knowledgeable than yourself, within
the limits provided by time, complexity and tolerance.
- Nor
Well, if buf is a character pointer to an array of size bufSize, just do:
std::string(buf,bufSize).find()
It's easier and more efficient to just properly create the string versus trying to parse the whole thing twice.