Использование двух строковых потоков, но не получение одинакового результата

Я пытаюсь сделать и напечатать матрицу, которая будет получать свои данные из текстового файла. Чтобы иметь возможность выровнять выходные данные (то есть как данные матрицы), я сначала извлек данные из файлов в виде строк, используя stringstream, чтобы получить наибольшее количество символов, которое будет иметь элемент в моей матрице. После этого я помещаю эту строку обратно в другой поток строк, а затем извлекаю их в двойное число в соответствии со спецификациями моего проекта. Проблема заключается в том, что всякий раз, когда у меня есть данные в моем текстовом файле, которые разделены только пробелами (НЕ НОВАЯ ЛИНИЯ), он получает только первый элемент строки.

while(getline(file, line) && size < (rows*columns))
{
  stringstream s1(line);
  stringstream s2;
  string temp;
  double toAdd;

  while(s1 >> temp && size < (rows*columns)) 
  {
    if(temp.size() > columnWidth2)
      columnWidth2 = temp.size();

    s2 << temp;
    s2 >> toAdd;

    cout << "Size: " << size << "\nTo Add: " << toAdd << "\nTemp: " << temp << '\n';
    dataContainer[size] = toAdd;
    size++;
    s2.str(string());
  }
}

Например, у меня есть текстовый файл с этими данными:

1 2 3 4 5
6
7
8
9
10

Если я выведу все содержимое моего dataContainer, оно будет выглядеть так:

1 1 1 1 1 6 7 8 9 10

вместо:

1 2 3 4 5 6 7 8 9 10

Что я делаю неправильно?

1 ответ

Решение

Почему бы тебе просто не использовать

while(s1 >> toAdd && size < (rows*columns)) 

вместо

while(s1 >> temp && size < (rows*columns)) 

или вы можете определить stringstream s2 внутри while блок, как это:

while(s1 >> temp && size < (rows*columns)) 
  {
    if(temp.size() > columnWidth2)
      columnWidth2 = temp.size();
    stringstream s2;
    s2 << temp;
    s2 >> toAdd;

    cout << "Size: " << size << "\nTo Add: " << toAdd << "\nTemp: " << temp << '\n';
    dataContainer[size] = toAdd;
    size++;
    s2.str(string());
  }

Лучший способ сделать это, это добавить s2.clear() после s2.str(""), clear() может сбросить состояние ошибки в потоке строки (в данном случае: eof)... потому что вы вызвали operator>> сразу после operator<<, s2 достиг конца файла и установил состояние eof. Согласно C++ Reference, если вы попытаетесь прочитать конец файла, вы потерпите неудачу, и тогда будет настроено "состояние отказа". Это причина, почему s2 может получить только первый элемент. Вот коды для изменения:

  while(s1 >> temp && size < (rows*columns)) 
  {
    if(temp.size() > columnWidth2)
      columnWidth2 = temp.size();
    s2 << temp;
    s2 >> toAdd;

    cout << "Size: " << size << "\nTo Add: " << toAdd << "\nTemp: " << temp << '\n';
    dataContainer[size] = toAdd;
    size++;
    s2.str(string());
    s2.clear(); //it can clear the eof state
  }
Другие вопросы по тегам