ifstream — C ++: чтение из текстового файла с несколькими разделителями

Есть ли способ чтения из файла, содержащего студенческие записи, но разделенные разными символами? Мой текст как ниже:

125 {John_BROWN_Biology} {100_81}
245 {Amanda_SMITH_Chemistry} {83_74}
436 {Michael_CLARK_Calculus} {35_48}

Я должен хранить в отдельных массивах, чтобы я мог рассчитать их среднее значение и поместить в порядке возрастания.
Я написал код на C ++ следующим образом:

int rank;
char st_info[SIZE];
int grades[SIZE];
bool success1 = false;
bool success2 = false;
bool success3 = false;

ifstream inFile;
inFile.open("records.txt");
string line;
int i=0, j=0;
while (!inFile.getline(rank, 30, '{').eof){
inFile.getline(st_info, SIZE, '_');
inFile.getline(words_array, SIZE, '_');
}
while (!success1)
{
getline(inFile,Line,'{'); // get values for info array
stringstream iss1;
iss1 << Line; //Put the string into a stream
iss1 >> rank; //To send data as an int.
cout << "STUDENT NUMBER:" << rank << "  ";
while (!success2){
// for the info in {} part
getline(inFile,Line,'_');
stringstream iss;
iss << Line;
iss >> st_info[i];
cout <<"STUDENT INFO:" << st_info[i] << "   ";
i++;
if (getline(inFile,Line,'}')){
stringstream iss2;
iss2 << Line;
iss2 >> st_info[i];
cout << st_info[i] << " ";
i=0;
success2 = true;
}
}
getline(inFile,Line,'{');
stringstream iss3;
iss3 << Line;
iss3 >> grades[j];
cout << "GRADES: "<< grades[i] << " ";
j++;
while (!success3){
getline(inFile,Line,'_');
stringstream iss4;
iss4 << Line;
iss4 >> grades[j];
cout << grades[i] << "  ";
j++;
if (getline(inFile,Line,'}')){
stringstream iss5;
iss5 << Line;
iss5 >> grades[j];
cout << grades[i] << "  ";
j=0;
success3 = true;
}
}
}

Тем не менее, в качестве вывода я получаю:

1 J 100
2 A 100
4 M 100

Пытался исправить, но стало еще хуже. Кто-нибудь может помочь? Заранее спасибо.

1

Решение

Есть несколько проблем с вашим подходом и вашим кодом:

  • istream::getline() не могу прочитать целые числа. Он может только читать в массив массивов символов.
  • eof это функция, а не свойство
  • как вы смешиваете << >> проанализировать данные с stringstream не оптимально.
  • с >>st_info[i] Вы извлекаете один символ из потока строк, который перезаписывает существующую информацию.
  • и конечно другие проблемы.

Поэтому я предлагаю вам использовать следующий скелет, который читает файл построчно и анализирует каждую строку отдельно, используя поток строк. Обратите внимание, что я использую только не членский вариант getline() читать строки вместо массивов char (это освобождает меня от мысли о переполнении буфера):

...
char delim;
int rank;
string names, grades;
string line;

while (getline(inFile, line))   // read line by line
{
stringstream sst{line};     // then parse the line using a string stream

sst>>rank;                  // read an integer
sst>>delim;                 // skip white and read a single char
if (delim!='{') {
cout<<"Error on line: { expected for name instead of "<<delim<<endl;
continue;   // next line, please !!
}
getline(sst,names, '}');  // TO DO: error handling
sst>>delim;
if (delim!='{') {
cout<<"Error on line: { expected for grades instead of "<<delim<<endl;
continue;   // next line, please !!
}
getline(sst,grades, '}');  // TO DO: additional error handling

cout << rank<<" "<<names<<" "<<grades<<endl; // temporary:

// TO DO: parse names and grades by using further stringstreams
}

Онлайн демо

Обратите внимание, что я использовал простой подход разбора: прочитайте символ и убедитесь, что он соответствует ожидаемому открывающему символу, и используйте getline() читать до закрывающего символа (последний используется, но исключается из строки). Это не позволяет для вложенных {...} в вашем формате.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]