2016-03-06 4 views
2

Так что мой text.txt выглядит следующим образом:C++ ошибка чтения файла

208 84 Sally Goodnow  30:23 52 F Lancaster 
209 344 Scott Grady   30:28 42 M Clinton 
210 191 gail holland  30:36 52 F worcester 
211 43 Karen Hughes  30:45 46 F Shirley 
212 221 Edward m Powers Jr. 30:48 60 M Clinton 
213 173 Lisa Zancewicz  30:49 34 F Clinton 
214 186 Julianne Ryll  30:54 51 F Clinton 
215 245 Briana Gibson  30:54 27 F Marlborough 

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

int a; 
int b; 
string c; 
string d; 
string e; 
string f; 
string g; 
string h; 

string mystr; 
int mymin; 
int mysec; 

int i; 


int count=0; 
while((infile>>a>>b>>c>>d>>e>>f>>g)&&getline(infile, h)) 

мой код просто разрывает на линии 212, я думаю, это связано с именем Edward m Powers Jr. (теперь я действительно ненавижу это имя, каждый раз, когда я смотрю на него, lol). Имя использует мои четыре строки, делая h = 60 M Клинтон. Это потому, что строка h не может хранить в ней целое число 60? Я не думаю, что это причина.

Я делаю getline (infile, h), потому что меня не интересует название города, Ланкастер, Клинтон - названия городов.

Я попытался пропустить линию 212, я сделал что-то вроде этого:

string all 
while(getline(infile, all) 
{ 
    if(all.at[0]!='2'&&all.at[1]!='1'&&all.at[2]!='2') 
    { 
     infile>>a>>b>>c>>d>>e>>f>>g; 
     getline(infile, h); 

Я делаю это просто строка 212 пропустить, но это не сработало. Он просто ломается в других строках.

ответ

3

Мне кажется, что, как минимум, половина вопросов, обрабатывающих входные данные здесь, на stackoverflow.com связана с оператором >>. Мне никогда не нравилось использовать этого оператора. Он имеет определенную жесткую семантику, влияющую как на парсинг ввода, так и на состояние ошибки входного потока, и если вход не совпадает с той же семантикой, использование оператора >> не будет работать надежно.

И, добавляя оскорбление к ранению, в реальном мире вход редко встречается для 100% от >>.

В этом случае проблема заключается в том, что вы не должны использовать оператор >>. Оператор >> предназначен для разбора строк с разделителями пробелов. Вы правильно определили, более или менее, где ваша проблема, теперь вам просто нужно сделать один последний шаг, чтобы завершить свое обучение в качестве джедая, и полностью остановить оператора >>. Вы не можете легко использовать его для анализа такого ввода.

Ваш ввод выглядит как пучок полей с фиксированной шириной. Поля всегда занимают одинаковые позиции символов в каждой строке. Вот что мне кажется. Оператор >> не предназначен для анализа такого ввода.

Скорее вы должны считывать ввод по одной строке за раз, используя std::getline(), а затем используя метод substr(), чтобы извлечь каждое поле из соответствующих позиций символа. Затем для каждого отдельного поля обрезайте конечное пустое пространство, которое тривиально.

P.S. Вы даже не используете оператор >> на нужном объекте. Вы уже используете std::getline() для чтения каждой строки ввода, но затем необъяснимо используйте оператор >> на объекте входного потока. Это неверно. Вам нужно проанализировать только что прочитанную строку, а не следующий вход в файл, построив std::istringstream на основе только что прочитанной строки, затем используя оператор на , этот объект. Но, как я уже сказал, вы не должны использовать оператора >> в любом случае ...