чтение в строках и удвоения

#c #string #double

#c #строка #двойное

Вопрос:

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

примером входного файла является:

 John Smith
019283729102380
300.00
2000.00
Andrew Lopez
293481012100121
400.00
1500.00
  

код читает:

 while(! infile.eof())
{
getline(infile,accname[count],'n');
getline(infile, refuse, 'n');  
getline(infile,accnum[count],'n');
getline(infile, refuse, 'n');  
infile>>currbal[count];  
getline(infile, refuse, 'n');  
infile>>credlim[count];  
getline(infile, refuse, 'n');  
count  ;
}
  

Комментарии:

1. Что не сработало? Какие входные данные вы ему ввели и что произошло?

2. @Oli, это действительно просто заморозило программу, а затем я закомментировал «отказывается» и инфайлы, относящиеся к удвоениям, и она запустилась (при выводе мусора)

3. Связано только частично: while(!infile.eof()) { /* read data */ } почти наверняка ошибка. Не ошибка , а баг.

4. Не могли бы вы сказать мне, в какой книге по C вам рекомендовано использовать функцию eof ()? Тогда я могу выйти и убить автора. И если вы не можете сказать мне, из какой книги вы это взяли, почему вы это используете?

5. @Sam, да, это ошибка. infile.eof() не могу предсказать, что предстоящее чтение столкнется с EOF. Рассмотрим эту программу . После того, как он правильно прочитает «3», он останавливается на последней новой строке. Поскольку бит EOF еще не установлен, он пытается прочитать значение после «3», и происходят плохие вещи.

Ответ №1:

РЕДАКТИРОВАТЬ: Обновлено в ответ на разъяснение OP.

Основываясь на предоставленном вами примере, это должно сработать:

 while(1) {
    std::string s1;
    if(!std::getline(infile, s1))
        break;
    std::string s2;
    if(!std::getline(infile, s2))
        break;
    double d1, d2;
    if(!(infile >> d1 >> d2))
        break;
    accname[count] = s1;
    accnum[count] = s2;
    currball[count] = d1;
    credlim[count] = d2;
    count  ;
}
  

Этот код будет работать для ввода типа:

 Adam Sandler
0112233
5 100
Ben Stein
989898
100000000
1
  

Но это не будет работать для ввода, подобного:

 Adam Sandler

0112233

5 100

Ben Stein

989898

100000000

1
  

Ответ №2:

Я думаю, что в ответе Роба Адамса есть небольшая ошибка при разборе нескольких записей. После извлечения d2 в первый раз входной поток примера будет содержать nBen Steinn989898n100000000n1 , поэтому следующий вызов std::getline() будет извлекать пустую строку вместо Ben Stein . Поэтому представляется необходимым использовать пустую строку в конце каждой итерации цикла while.

Я думаю, что следующий пример кода обеспечивает исправление:

 #include <iostream>
#include <sstream>

int main(int argc, char** argv) {
  using std::stringstream;
  stringstream infile(stringstream::in | stringstream::out);

  infile << "John Smithn";
  infile << "019283729102380n";
  infile << "300.00n";
  infile << "2000n";
  infile << "Andrew Lopezn";
  infile << "293481012100121n";
  infile << "400.00n";
  infile << "1500.00n";

  std::string account_name;
  std::string account_number;
  double current_balance;
  double credit_limit;

  int count = 0;

  while (std::getline(infile, account_name) amp;amp;
         std::getline(infile, account_number) >> current_balance >>
         credit_limit) {

    std::cout << account_name << std::endl;
    std::cout << account_number << std::endl;
    std::cout << current_balance << std::endl;
    std::cout << credit_limit << std::endl;

    /*
    accname[count] = account_name;
    accnum[count] = account_number;
    currball[count] = current_balance;
    credlim[count] = credit_limit;
    */

    count  ;

    // Consume the leading newline character, which seprates the credit limit
    // from the next account name, when infile contains multiple records.
    //
    // For example, after consuming the record for John Smith, the stream will
    // contain: "nAndrew Lopezn293481012100121n400.00n1500.00n". If you
    // don't consume the leading newline character, calling std::getline() to
    // parse the next account name will extract an empty string.
    std::string blank;
    std::getline(infile, blank);
  }

  return 0;
}
  

Ответ №3:

 string str;

while(!infile.eof())
{
    getline(infile, accname[count]);//  you do not need 'n' it will always read to 
                     // end of the line

    getline(infile, accnum[count]);

    getline(infile, str);
    currbal[count] = atof(str.c_str());

    getline(infile, str);
    credlim[count] = atof(str.c_str());

    count  ;
}

* 
for the file 
John Smith
019283729102380
300.00
2000.00
Andrew Lopez
293481012100121
400.00
1500.00
*