Skip to main content
GameDev.net gamedev.net
🔒 Locked

C++ fstream behavior

Started by antiquechrono Jul 5, 2007 at 3:23 PM 3 replies 1.4k views
Original Post
antiquechrono
antiquechrono
When I open a file and start reading from it the stream fails when it reads characters it apparently does not like. I was under the impression that the read function did not care what the data meant and only transfered bytes around. In particular it fails when it encoutners 0x1A. However if you open the file in binary mode everything works fine. I am just wondering if anyone has a technical explination? Simple Example of the working version:

#include <iostream>
#include <fstream>

using namespace std;

int main(){
	
	ifstream file;
	file.open("test.txt", ios::binary);
	if(file.is_open())
		cout << "file opened" <<endl;

	char buff;

	//while(file >> buff)
	//	cout << buff;

	while(file.read((char*)&buff,1))
		cout << buff;

	return 0;
}
Zahlman
Zahlman
The way in which you read from/write to a file is separate from the way in which you open it. Normally, you are expected to use 'formatted' I/O operations (the operators >> and <<) with a file open in text mode, and the raw operations (.read() and .write()) with a file open in binary mode, but nothing prevents you from mixing and matching.

In binary mode, the bytes seen in the file are the bytes that are actually there.

In text mode, the interpretation is platform-dependent. Some sorts of translation are done, depending on the system:

1) The combination of a carriage return and line-feed may get translated into a single newline character (Windows does this). This is intended to make it easier to deal with old DOS text files (it's easier to detect single characters as line-endings; in particular, this will make things like std::getline() work right - if you used that on a file opened as binary on a Windows machine, you might get an extra byte stuck in each read-in line).

2) A certain character (on Windows, this is ASCII 26, i.e. 0x1A) is interpreted as indicating the end of file: once it's seen, the rest of the file's contents are ignored. The reason for this is to make it possible to indicate the "end of file" on a console stream. Consider for example:

#include <iostream>using namespace std;int main() {  char c;  cout << "Feel free to type whatever you like; I'm ignoring you..." << endl;  while (cin >> c) {};  cout << "OK, I guess you're done now." << endl;}


When the user hits control-Z, this creates the EOF (end-of-file) character mentioned above; so if the user hits control-Z and then return, the control-Z will be read in by the loop, causing it to terminate and the program to exit.
antiquechrono
antiquechrono
Thanks a ton, it all makes a lot more sense in that context. I never realized that ^Z was the eof character which makes me feel dumb since i was just playing with it in Linux lol.
Sharlin
Sharlin
^Z is only EOF on Windowsen; on Unix-like systems it sends SIGSTOP, and EOF is ^D.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.