У меня есть очень простой код, и его функциональность заключается в вводе имени файла, из которого программа будет считывать данные. Поскольку файл может быть неправильным из-за опечатки, консоль будет продолжать просить пользователя ввести имя, если предыдущее имя неверно.
Проблема в том, что, хотя первый цикл do-while работает нормально, программа пропустит второй цикл while, если имя файла введено неправильно в первый раз в первом цикле. Однако, если имя файла введено правильно, все работает нормально.
Интересно, почему программа ведет себя так.
Спасибо за вашу помощь и ваше время!
#include<iostream>
#include<fstream>
using namespace std;
int main() {
string context;
int step=0,i=0;
ifstream fin;
do {
string filename;
cout << endl << "please type in the name of input file" << endl;
cin >> filename;
string filepath = "files/" + filename;
cout << filepath << endl;
fin.open( filepath.c_str() );
} while( !fin.is_open() );
while (getline(fin, context)){
cout << context << endl;
cout << "hello" << endl;
}
fin.close();
return 0;
}
Я думаю, что состояние «плавник» может испортиться после первой попытки.
Почему бы вам не попробовать вызвать fin.clear () перед вызовом fin.open ().
Из стандарта,
27.8.1.10
void open(const char* s, ios_base::openmode mode = ios_base::out);
Вызовыrdbuf()->open(s,mode|out)
, Если эта функция возвращает нулевой указатель, вызывает
SetState (failbit).311a
Так что это за заметка 311a?
311a Успешное открытие не меняет состояние ошибки.
Хотя примечания не являются нормативными, в нормативном тексте абсолютно ничего не говорится о том, что делает успешное открытие с состоянием ошибки, если rdbuf->open()
Был успешен. Примечание разъясняет это не утверждение.
Итог: вам нужно clear
биты состояния файлового потока перед вызовом open
когда вы перезваниваете open
после того, как это не удалось.
Вам нужно очистить свой ifstream, он может быть поврежден предыдущей попыткой файла.