2013-04-05 2 views
0

Кажется, что это не проблема, которая вызывает проблемы для меня. Я не понимаю. :/Не могу получить ios :: попросить вернуться к началу файла

Так что я стараюсь, чтобы я понял, как манипулировать текстовыми файлами. У меня есть два файла: «infile.txt» и «outfile.txt». «infile.txt» имеет шесть номеров в нем и ничего больше. Вот код, который я использовал для управления файлами.

#include<fstream> 
using std::ifstream; 
using std::ofstream; 
using std::fstream; 
using std::endl; 
using std::ios; 

int main() 
{ 
ifstream inStream; 
ofstream outStream;//create streams 

inStream.open("infile.txt", ios::in | ios::out); 
outStream.open("outfile.txt");//attach files 

int first, second, third; 
inStream >> first >> second >> third; 
outStream << "The sum of the first 3 nums is " << (first+second+third) << endl; 
//make two operations on the 6 numbers 
inStream >> first >> second >> third; 
outStream << "The sum of the second 3 nums is " << (first+second+third) << endl; 

inStream.seekg(0); //4 different ways to force the program to go back to the beginning of the file 
//2. inStream.seekg(0, ios::beg); 
//3. inStream.seekg(0, inStream.beg); 
//4. inStream.close(); inStream.open("infile.txt"); 
//I have tried all four of these lines and only #4 works. 
//There has got to be a more natural option than just 
//closing and reopening the file. Right? 

inStream >> first >> second >> third; 
outStream << "And again, the sum of the first 3 nums is " << (first+second+third) << endl; 

inStream.close(); 
outStream.close(); 
return 0; 
} 

Может быть, я не понимаю совершенно, как работает поток, но я видел несколько источников, которые считают, что seekg (0) следует переместить указатель назад в начало файла. Вместо этого я из этого выхожу.

Сумма первого 3 НУМСА 8

Сумма второго 3 НУМСА 14

И опять же, сумма первого 3 НУМСА является 14

Он вернулся, но не так, как я бы надеялся. Любая идея, почему это произошло? Почему мои первые три попытки потерпели неудачу?

+0

Что такое 'infile.txt'? В частности, каковы цифры? – Tushar

+0

@Tushar. Что еще более важно, каково его содержание в дополнение к цифрам. Должно быть больше, так как вам нужно пустое пространство для разделения чисел. Если файл заканчивается на '' \ n'' (который должен быть, если это текстовый файл), то все, кроме первого метода, который он использует, гарантируется стандартом (и первый будет работать и на практике). –

+0

Также важным является используемый им компилятор/библиотека. C++ 11 определяет 'seekg' иначе, чем C++ 03. –

ответ

3

Как утверждает Бо Перссон, это может быть, потому что ваш вход имеет столкнулся с концом файла; он не должен, потому что в C++ текст определяется как завершаемый '\n', но практически говоря, если вы работаете под Windows, много способов создания файла опускают этот окончательный '\n' — хотя формально требуется , практические соображения будут означать, что вы убедитесь, что он работает, даже если окончательный '\n' отсутствует отсутствует. И я не могу думать ни о какой другой причине, почему seekg не будет работать. inStream.seekg(0) - это, конечно, неопределенное поведение, но на практике он будет работать в целом везде. inStream.seekg(0, ios::beg) гарантируется Работа еслиinStream.good(), и есть, ИМХО, предпочтительнее первая форма. (Форма одного аргумента seekg обычно используется только в качестве аргумента.) И Конечно, он работает только в том случае, если фактический источник входного сигнала поддерживает , ища: он не будет работать, если вы читаете с клавиатуры или труба (но предположительно, "infile.txt" не является ни).

В общем, вы должны проверить статус inStream после каждого прочитайте, прежде чем использовать результаты.Но если единственная проблема заключается в том, что файл не заканчивается '\n', вполне вероятно, что статус будет в порядке (!fail()) после окончательного чтения, даже если у вас есть столкнулся с концом файла. В этом случае вам понадобится clear() .

Обратите внимание, что приведенные выше комментарии действительны для C++ - 03 и прецедента. C++ 11 изменил спецификацию формы одного аргумента от seekg и требует ее сброса eofbitдо ничего еще. (Почему это изменение только для одной аргумента формы seekg, а не две формы аргумента? Надзор?)

+0

Это прекрасно. Я забыл включить конечный '\ n', но MSVC++ не считал это достойным предупреждения. Кроме того, inStream.clear() также работал. Спасибо всем за советы. – anthony

+0

@anthony Проблема с '' \ n'' в мире Windows заключается в том, что, похоже, нет никакого соглашения относительно того, является ли CRLF разделителем или терминатором. Библиотека VC++ рассматривает ее как терминатор, но большинство других программ рассматривают ее как разделитель. (Если это логически разделитель, 'filebuf' должен автоматически генерировать' '\ n'', когда он достигнет конца файла, и не должен выводить ничего для окончательного' '\ n'', который вы выведете. Только в текстовом файле конечно. Практически единственное, что нужно сделать, - это ожидать, что окончательный '' \ n'' будет отсутствовать, а это произойдет (даже в Unix). –

0

Try:

inStream.seekg(0, ios_base::beg); 
+0

Он сказал, что не работает (хотя должна). –

+0

На самом деле, я никогда не пробовал. В чем разница между этим и (0, ios :: beg)? – anthony

2

Второй вход достигает окончание срока файла для потока. Это состояние прилипает, пока вы не позвоните inStream.clear(), чтобы очистить его состояние (в дополнение к поиску).

С компилятором, совместимым с C++ 11, параметр 4 также должен работать как можно ближе и снова открыть, теперь очистит предыдущее состояние. Старые компиляторы могут этого не делать.

+0

В C++ 11 'seekg' очищает eofbit. Однако могут быть установлены другие флаги ошибок. – jrok

+0

На самом деле, неясно, что он достиг конца файла. Если в шести файлах есть пробел в файле, у него его не будет. (И логически, поскольку это текстовый файл, после последнего числа должно быть не менее '' \ n''. –

+0

@jrok Только одна форма аргумента сбрасывает 'eofbit'. Но форма одного аргумента - это неопределенное поведение, если оно вызвано интегральной константой. И если входной файл на самом деле содержит 6 номеров, 'eofbit' - единственная возможная проблема. –

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