Чтение файла - не открывается

Я пытаюсь открыть файл на С++, но, похоже, это доставляет мне немного хлопот, вот код, который до сих пор имеет дело с открытием файла:

void CreateHistogram(string str_file, vector<HistogramWord> &result) {
    string line;
    long location;
    HistogramWord newWord;
    const char * filename = str_file.c_str();

    //ifstream myfile (str_file.c_str());
    ifstream myfile (filename);
    //myfile.open(filename);
    if (myfile.is_open()) {
        while (myfile.good()) {
            getline(myfile, line);
            line = clarifyWord(line);

Хорошо, просто для небольшого пояснения: HistogramWord — это структура, которая определена в заголовке, и из того, что я прочитал в онлайн-документации, имя файла должно быть типа const char *, что я и сделал. Преобразование str_file в const char *.

Теперь я пробовал несколько разных вещей, поэтому часть кода закомментирована. Когда он доходит до строки if (myfile.is_open()), он всегда оценивается как false. Кажется, кто-нибудь знает, почему?

Спасибо, Брэндон


person Brandon    schedule 17.09.2011    source источник
comment
Да, он существует и находится в том же каталоге, что и основная функция, поэтому я должен просто вызвать его как test.txt, верно?   -  person Brandon    schedule 17.09.2011
comment
Я также только что попробовал это с раскомментированным myfile.open(filename);, и он все еще не хочет работать:/   -  person Brandon    schedule 17.09.2011
comment
Пожалуйста, распечатайте имя файла и скопируйте его в адресную строку, проводник или любой другой инструмент, который вы используете, и проверьте существование файла.   -  person FailedDev    schedule 17.09.2011
comment
Незадолго до прочтения вашего комментария FailedDev я нашел веб-сайт, на котором объясняется, что если вы не укажете полный путь к файлу, он будет выглядеть в том же каталоге, что и объектный файл, который фактически находится в папке TEMP в Windows. Он не входит в оператор if, поэтому файл открыт. Однако линия, которая не работает, это while (myfile.good()) {, она не входит в этот цикл. Есть ли другой способ прочитать содержимое файла без этого цикла? Это не кажется очень полным доказательством.   -  person Brandon    schedule 17.09.2011
comment
@Brandon - в любом случае просто сделайте while (std::getline(...)), он возвращает istream, который перегружен, поэтому вы можете использовать его таким образом. (Кстати: я полагаю, вы имели в виду защиту от дурака?)   -  person Flexo    schedule 17.09.2011
comment
std::getline(), какие параметры он примет?   -  person Brandon    schedule 17.09.2011
comment
getline(myfile, line) как у вас, но как условие цикла while.   -  person Flexo    schedule 17.09.2011
comment
Я пробовал это, и он все еще не входит в цикл. Используя точки останова, он работает на всем, пока не появится цикл while. Если это поможет, вот текстовый файл, который я пытаюсь прочитать: http://pastebin.com/Su76fNFC.   -  person Brandon    schedule 17.09.2011
comment
РЕДАКТИРОВАТЬ: я могу войти в цикл, ЕСЛИ я изменяю условие на !myfile.eof(), но затем, используя getline(myfile, line) в цикле, line назначается "", что неверно в файле.   -  person Brandon    schedule 17.09.2011
comment
Вы пытались запустить свое приложение из каталога приложения?   -  person Yeheshuah    schedule 21.08.2019


Ответы (3)


OK IO 101

Если вы не укажете полный путь к файлу, а только имя файла, то текущий рабочий каталог будет добавлен к имени файла.

Итак, если ваш .exe находится в C:\temp, и вы вызываете свою программу из этого каталога, а имя вашего файла — test.txt, то полное имя файла в этом случае будет C:\temp\test.txt.

Это будет работать только в том случае, если .exe и test.txt находятся в папке C:\temp.

Во всех остальных случаях не получится. Вы можете создать абсолютный путь, используя win API или эквивалент Linux — я не знаю, на какой платформе вы работаете.

Теперь, чтобы прочитать успешно открытый файл, этого будет достаточно:

void CreateHistogram(string str_file, vector<HistogramWord> &result) {
string line;
long location;
HistogramWord newWord;

ifstream myfile (str_file.c_str());
if (myfile.is_open()) {
    while (getline(myfile, line)) {
        line = clarifyWord(line);
}
else{
   //throw exception, print error message etc
   throw std::exception(std::string("Couldn't open file : " + str_file).c_str());
}
}

редактировать: Спасибо @ Shahbaz

person FailedDev    schedule 17.09.2011
comment
На самом деле он должен находиться в каталоге, из которого вы вызываете файл .exe. Поэтому, если вы находитесь в каталоге C:\ и вызываете temp\test.exe, он ожидает, что он будет в C:\, а не в C:\temp. - person Shahbaz; 17.09.2011

Я думаю, что Windows «скрывает расширения для известных типов файлов», поэтому имя файла на самом деле отличается от того, что вы указали в окнах. Например, если это файл .txt, и вы называете его test.txt, фактическое имя будет test.txt.txt, что довольно глупо для Windows.

Чтобы изменить это, перейдите в «Мой компьютер» -> «Инструменты» -> «Свойства папки» -> и снимите флажок «Скрыть расширения для известных типов файлов». Это для ХР. Если у вас есть другие окна, это должен быть более или менее тот же путь. Если вы не видите панель инструментов, попробуйте ALT+t (инструменты) или ALT+f (файл), чтобы она появилась.

Эта проблема доставляет немало хлопот многим из нас в первом семестре колледжа.

person Shahbaz    schedule 17.09.2011

Что исправило это для меня, так это использование косой черты вместо двойной обратной косой черты в моем пути к файлу.

e.g.

inFile.open("path/to/file.txt")

вместо

inFile.open("path\\to\\file.txt")
person Victor Burnett    schedule 21.08.2019