Reputation: 62
I have a file and I wish to separate items in the file by line. The indicator for the end of an item is a semicolon. So when I come across a semicolon, I want to put everything after the semicolon on a newline. And continue until i find the next semicolon and repeat.
char c;
fstream distances;
distances.open(argv[1]);
while(distances >> c) {
if(c == ';') {
distances << endl;
}
}
This is the code inside main. It is opening the file correctly. The file says
i;am;testing;this
but after running the program the file reads:
i;
;
sting;
is
I'm not sure why it would delete the two characters following the semicolon. Unless it is using that space for \n character. If anyone could help or suggest a more efficient solution I would appreciate it.
Upvotes: 1
Views: 83
Reputation: 24249
The fstream
object you have is a representation of the bytes on disk. If 'insert' writes were allowed, the program would have to move every byte in the file after the insert point up by one position, essentially rewriting the file.
The only way to get an implemention of an 'insert' ability is to do it yourself, generally using a new file (you could do it in the same file by reading the rest of the file into memory, going back to the insert position, overwriting the character, and then writing your buffered copy of the file from before).
The reason that the next two characters are being overwritten is as follows:
// file buffer = [i][;][a][m][;][t]...
// position ^
distances >> c;
// c = [i]
// file buffer = [i][;][a][m][;][t]...
// position ^
distances >> c;
// c = [;]
// file buffer = [i][;][a][m][;][t]...
// position ^
distances << endl;
std::endl
writes the local line ending sequence and issues a std::flush
to force writing. Under Windows, endl
produces the sequence file << '\r' << '\n' << std::flush;
The stream position is where the 'a'
is, not where the ';' is - by reading that character you advanced the stream position past it, so it writes the '\r'
over the 'a'
and the '\n'
over the 'm'
.
// file buffer = [i][;][a][m][;][t]...
// position ^
distances << '\r'
// file buffer = [i][;][\r][m][;][t]...
// position ^
distances << '\n'
// file buffer = [i][;][\r][\n][;][t]...
// position ^
distances >> c;
// c = ';'
// file buffer = [i][;][\r][\n][;][t]...
// position ^
Upvotes: 1
Reputation: 385194
Despite the illusion presented by text editing software, you can't "insert" into a file. You can only read its contents, modify them in memory, then write them back out again.
Your two characters are being replaced by your newline which, on Windows, actually consists of a Carriage Return followed by a Line Feed.
Upvotes: 3
Reputation: 118340
The most likely explanation is that you're using Microsoft Windows, where the newline sequence is two characters: a carriage return and a line feed: \r\n
.
On Microsoft Windows a std::endl
will write two characters: an \r
and an \n
.
Upvotes: 1