Build std :: string with up to X char actors, stopping at zero char

I read lines from a structure in a file, where each line has a fixed length, indented '\0' . They do not end with zero if the stored string needs the full length.

I am currently creating std::string from these:

 // char MyString[1000]; std::string stdmystring(MyString, ARRAYSIZE(MyString)); 

However, this also copies the add-on. I could trim the string now, but is there an elegant and quick way to prevent copying in the first place?

Speed ​​is more important than space because it runs in a loop.

+5
source share
3 answers

Simple solutions:

  • Just calculate the correct length first

    • either use strnlen as suggested by Dieter
    • or std::find(MyString,MyString+ARRAYSIZE(MyString),'\0') , which IME is not slower

    note that if your line matches the cache, this will probably dominate the extra cost of the loop

  • reserve the maximum row size (you said space was less important) and write loops adding characters until you run out of width or hit zero (e.g. copy_until )

  • actually create a max-size string initialized with nuls, strncpy , and possibly remove unused nuls if you want the size to be correct

The second option uses only one loop, while the third, as a rule, uses two (this is in the ctor line, and then in the copy). However, the push_back each character seems more expensive than simply assigning a character, so I won’t be surprised if # 3 is actually faster. Profile and see!

+2
source

Well, if size is not a problem, one possible way to do this is to create an empty std::string , and then use reserve() to preallocate the potentially necessary space, and then add each char until you encounter '\0' .

 std::string stdmystring; stdmystring.reserve(MyString_MAX_SIZE) ; for(size_t i=0;i<MyString_MAX_SIZE && MyString[i]!='\0';++i); stdmystring+=MyString[i]; 

reserve() guarantees you memory allocation, since you know max_size, and the string will never be anymore.

A call to the + = operator function will probably be inlined, but you still need to verify that the line has the required bandwidth, which is useless in your case. Infact it can be the same or worse than just using strlen to find the exact length of the string first so you can test it.

+2
source

I think the easiest way is to concatenate your internal MyString array into one byte, always with zero completion of this final byte, and use the C-string std::string constructor. (Keep in mind that most likely your process will be bound to the I / O in the file, so any algorithm that uses the C-string constructor should be accurate).

0
source

All Articles