2013-03-26 2 views
2

Я пишу программу, которая должна будет импортировать данные из файла в различные контейнеры. Я импортирую все правильно, но он продолжает читать после того, что должно быть эф. У меня такое чувство, что я не говорю о том, когда заканчивать, но код ниже для всех, на что можно смотреть.ifstream still reading after eof

bool InitLoad(vector<string>&num, vector<string>&name, vector<double>&price, vector<char>&tax) 
{ 
    ifstream invFile; 
    int intTemp; 
    string strTemp; 
    double dubTemp; 
    char chTemp; 
    string fileLoc = "C:/Users/owner/Documents/Visual Studio 2010/Projects/CISS 350/Week 1 Grocery Register/Week 1 Grocery Register/Invent.dat"; 

    //Open Invent.dat file. Location below is the location used on creators computer. Other may need to modify file location 
    invFile.open(fileLoc.c_str(), ios::in); 

    //If Invent.dat file fails to open display error message and return false 
    if(invFile.fail()) 
    { 
     cout << "Could not open inventory file" << endl; 
     return false; 
    } 
    if(invFile) 
    { 
     //Read first line of the file 
     getline(invFile, strTemp, ' '); 
     while(invFile) //while invFile contains data display import the list 
     { 
      cout << strTemp << " "; 
      num.push_back(strTemp); 

      getline(invFile, strTemp, ' '); 
      cout << strTemp << " "; 
      name.push_back(strTemp); 

      getline(invFile, strTemp, ' '); 
      dubTemp = atof(strTemp.c_str()); 
      cout << dubTemp << " "; 
      price.push_back(dubTemp); 

      invFile.get(chTemp); 
      cout << chTemp; 
      tax.push_back(chTemp); 

      getline(invFile, strTemp, ' '); 
     } 
    } 

    invFile.close(); 

    cout << endl; 
    //Verify Proper input...REMOVE WHEN COMPLETE 
    cout << "Verifying input data correct..." << endl; 
    int vecSize = num.size(); 
    cout << vecSize << endl; 
    for(int i = 0; i < vecSize; i++) 
    { 
     cout << num[i] << " " << name[i] << " " << price[i] << " " << tax[i] << endl; 
    } 

} 
+0

Вы пытались позвонить во время (! InvFile.eof())? –

+0

@fatih_k Это была бы серьезная ошибка. Он на правильном пути. Ему просто нужно проверить после каждого 'getline', чтобы убедиться, что он преуспел. –

ответ

4

Ваш чек не проверяет ВФ флаг http://www.cplusplus.com/reference/ios/ios/operator_bool/

использовать invFile.eof() вместо

А также ВФ флаг будет выставиться после чтения мимо EOF

PS: OMG !! не используйте atof, просто выполните invFile << dubTemp

+0

После того, как я посмотрел немного ближе, файл, который я использовал, имел пробел после последнего бит данных, поэтому он не доходил до того, как цикл перезапускался. –

+0

Вот почему вы предлагаете использовать 'while (invFile << num_str << name_str << price_fl << tax_ch) {...}' form – kassak

+0

Это просто неправильно. Пока вы не знаете, что вход не сработал, 'invFile.eof()' не обязательно даст что-нибудь полезное. В частности, тот факт, что 'invFile.eof()' возвращает 'false' делает _not_, означает, что все еще есть данные для чтения. –

0

Поскольку ваши данные разделены пробелами, вы можете использовать форматированный вход вместо getline() для каждой строки. Что-то вроде этого.

string lineTemp; 
while(getline(invFile, lineTemp)) //while invFile contains data display import the list 
    { 
     string strTemp1, strTemp1, dubTemp, chTemp; 
     istringstream lstr(lineTemp); 

     if(lstr >> strTemp1 >> strTemp2 >> dubTemp >> chTemp) { 

      num.push_back(strTemp1); 
      name.push_back(strTemp2); 
      price.push_back(dubTemp); 
      tax.push_back(chTemp); 


      cout << strTemp1 << " " 
       << strTemp2 << " " 
       << dubTemp << " " 
       << chTemp << endl; 
     } 

     else { 
      // Something is wrong with the line format. 
     } 


    } 

Это будет считывать данные в строгом виде и в соответствующем типе. Кроме того, вам не нужно беспокоиться о пустых строках или дополнительных символах в строках.

+0

Это каноническое решение. Но определенно требуется проверка ошибок после чтения в цикле, а также перед использованием данных). –

+0

Да, это правильно. Я предполагаю, что он имеет строки во входном файле в этом точном формате. Конечно, если мы захотим, он сможет это сломать. – 2013-03-26 17:32:19

+0

Достаточно просто добавить проверку. Сначала прочитайте все переменные ('lstr >> strTemp1 >> strTemp2 >> dubTemp >> chTemp'), затем проверьте, правильно ли' lstr', прежде чем делать что-либо еще. –

Смежные вопросы