2010-08-18 6 views
2

Чтобы упростить, я пытаюсь прочитать содержимое CSV-файла, используя класс ifstream и его функцию getline(). Вот этот CSV-файл:Неожиданное поведение getline() с ifstream

1,2,3 
4,5,6 

И код:

#include <iostream> 
#include <typeinfo> 
#include <fstream> 

using namespace std; 

int main() { 
    char csvLoc[] = "/the_CSV_file_localization/"; 
    ifstream csvFile; 
    csvFile.open(csvLoc, ifstream::in); 
    char pStock[5]; //we use a 5-char array just to get rid of unexpected 
        //size problems, even though each number is of size 1 
    int i =1; //this will be helpful for the diagnostic 
    while(csvFile.eof() == 0) { 
     csvFile.getline(pStock,5,','); 
     cout << "Iteration number " << i << endl; 
     cout << *pStock<<endl; 
     i++; 
    } 
    return 0; 
} 

Я ожидаю, что все номера для чтения, так как GetLine предполагают, чтобы принять то, что написано после последнего чтения, и останавливаться при встрече «,» или «\ n».

Но, похоже, что он читает все хорошо, КРОМЕ «4», то есть первый номер второй линии (см консоли):

Iteration number 1 
1 
Iteration number 2 
2 
Iteration number 3 
3 
Iteration number 4 
5 
Iteration number 5 
6 

Таким образом, мой вопрос: что делает это «4» после (Я думаю), '\ n' настолько специфичен, что getline даже не пытается учесть это?

(Спасибо!)

ответ

6

Вы читаете через запятую значения так в последовательности вы читаете: 1, 2, 3\n4, 5, 6.

Вы распечатайте первый символ массива каждый раз: то есть 1, 2, 3, 5, 6.

Что вы ожидали?

Кстати, ваш чек на eof находится не в том месте. Вы должны проверить, успешно ли выполняется вызов getline. В вашем конкретном случае это в настоящее время не имеет значения, потому что getline что-то читает и запускает EOF всего за одно действие, но в целом он может провалиться, не прочитав ничего, и ваш текущий цикл все равно обработает pStock, как если бы он был повторно заселен.

В более общем-то, как это было бы лучше:

while (csvFile.getline(pStock,5,',')) { 
    cout << "Iteration number " << i << endl; 
    cout << *pStock<<endl; 
    i++; 
} 
+0

«Что вы ожидали?» На самом деле, если взглянуть на http://www.cplusplus.com/reference/iostream/istream/getline/, мне кажется, что getline действует с '\ n' так же, как и с указанным разделителем. А именно, просто останавливаясь, чтобы читать, когда он встречается (таким образом, как и с «1,2», он останавливается до 2, а «3 \ n4» должен остановиться до 4). Но я думаю, что это не тот случай, я не понимаю, что все хорошо! Спасибо за ответ. – Kamixave

+0

@Kamixave: С моим чтением cplusplus.com я не думаю, что это неправильно.'\ n' - это только разделитель по умолчанию, если вы его не поставляете. Если вы поставляете один, он используется вместо него (не так). –

+0

@Charles Bailey: Не могли бы вы добавить std :: getline (, ) пример. Эта версия имеет потенциал для переполнения буфера. –

3

AFAIK, если используется параметр терминатора, getline() читает до тех пор, пока не найдет разделитель. Это означает, что в вашем случае, он прочитал

3\n4 

в массив pSock, но печатать только первый символ, так что вы получите 3 только.

1

проблема с вашим кодом является то, что GetLine, когда Ограничитель указывается, «» в вашем случае, использует его и игнорирует разделитель по умолчанию ' \ п». Если вы хотите отсканировать этот файл, вы можете использовать функцию токенизации.

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