2

I asked this question before but with less information than I have now.

What I essentially have is a data block of type char. That block contains filenames that I need to format and put into a vector. I initially thought the formation of this char block had three spaces between each filename. Now, I realize they are '/0' null terminated characters. So the solution that was provided was fantastic for the example I gave when I thought that there were spaces rather than null chars.

Here is what the structure looks like. Also, I should point out I DO have the size of the character data block.

filename1.bmp/0/0/0brick.bmp/0/0/0toothpaste.gif/0/0/0

The way the best solution did it was this:

// The stringstream will do the dirty work and deal with the spaces.
   std::istringstream iss(s);

   // Your filenames will be put into this vector.
   std::vector<std::string> v;

   // Copy every filename to a vector.
   std::copy(std::istream_iterator<std::string>(iss),
    std::istream_iterator<std::string>(),
    std::back_inserter(v));

   // They are now in the vector, print them or do whatever you want with them!
   for(int i = 0; i < v.size(); ++i)
    std::cout << v[i] << "\n"; 

This works fantastic for my original question but not with the fact they are null chars instead of spaces. Is there any way to make the above example work. I tried replacing null chars in the array with spaces but that didn't work.

Any ideas on the best way to format this char block into a vector of strings?

Thanks.

2 Answers 2

2

If you know your filenames don't have embedded "\0" characters in them, then this should work. (untested)

const char * buffer = "filename1.bmp/0/0/0brick.bmp/0/0/0toothpaste.gif/0/0/0";
int size_of_buffer = 1234; //Or whatever the real value is

const char * end_of_buffer = buffer + size_of_buffer;

std::vector<std::string> v;

while( buffer!=end_of_buffer)
{
  v.push_back( std::string(buffer) );
  buffer = buffer+filename1.size()+3;
}

If they do have embedded null characters in the filename you'll need to be a little cleverer. Something like this should work. (untested)

char * start_of_filename = buffer;
while( start_of_filename != end_of_buffer )
{

  //Create a cursor at the current spot and move cursor until we hit three nulls
  char * scan_cursor = buffer;
  while( scan_cursor[0]!='\0' && scan_cursor[1]!='\0' && scan_cursor[2]!='\0' )
  {
     ++scan_cursor;
  }

  //From our start to the cursor is our word.
  v.push_back( std::string(start_of_filename,scan_cursor) );

  //Move on to the next word
  start_of_filename = scan_cursor+3;
}
Sign up to request clarification or add additional context in comments.

Comments

1

If spaces would be a suitable separator, you could just replace the null characters by spaces:

std::replace(std::begin(), std::end(), 0, ' ');

... and go from there. However, I'd suspect that you really need to use the null characters as separators as file names typically can include spaces. In this case, you could either use std::getline() with '\0' as the end of line or use the find() and substr() members of the string itself. The latter would look something like this:

std::vector<std::string> v;
std::string const null(1, '\0');
for (std::string::size_type pos(0); (pos = s.find_first_not_of(null, pos)) != s.npos; )
{
    end = s.find(null, pos);
    v.push_back(s.substr(0, end - pos));
    pos = end;
}

1 Comment

Thank you for the idea about having possible spaces in the names. Avoided a major possible headache down the road.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.