Разбор массива символов с несколькими символами с нулем в конце в разные строки - C ++ - PullRequest
1 голос
/ 30 декабря 2011

Я задавал этот вопрос раньше, но с меньшей информацией, чем сейчас.

По сути, у меня есть блок данных типа char. Этот блок содержит имена файлов, которые мне нужно отформатировать и поместить в вектор. Сначала я думал, что формирование этого блока символов имеет три пробела между каждым именем файла. Теперь я понимаю, что они являются символами '/ 0' с нулевым символом в конце. Таким образом, решение, которое было предоставлено, было фантастическим для примера, который я привел, когда подумал, что есть пробелы, а не нулевые символы.

Вот как выглядит структура. Кроме того, я должен указать на У меня действительно есть размер блока символьных данных.

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

Лучшее решение было так:

// 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"; 

Это прекрасно работает для моего первоначального вопроса, но не потому, что они являются нулевыми символами вместо пробелов Есть ли способ заставить приведенный выше пример работать. Я попытался заменить нулевые символы в массиве пробелами, но это не сработало.

Есть идеи, как лучше отформатировать этот символьный блок в вектор строк?

Спасибо.

Ответы [ 2 ]

1 голос
/ 30 декабря 2011

Если вы знаете, что в ваших именах файлов нет символов «\ 0», это должно сработать.(не проверено)

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

Если в имени файла есть встроенные нулевые символы, вам нужно быть немного умнее.Нечто подобное должно работать.(не проверено)

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;
}
1 голос
/ 30 декабря 2011

Если пробел будет подходящим разделителем, вы можете просто заменить нулевые символы пробелами:

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

... и иди оттуда. Однако я подозреваю, что вам действительно нужно использовать нулевые символы в качестве разделителей, поскольку имена файлов обычно могут содержать пробелы. В этом случае вы можете либо использовать std :: getline () с '\ 0' в качестве конца строки, либо использовать члены find () и substr () самой строки. Последний будет выглядеть примерно так:

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;
}
...