简体   繁体   English

在文件中插入新行会删除接下来的两个字符C ++

[英]Inserting a new line in a file deletes the next two characters C++

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. 这是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. 除非它为\\ n字符使用该空格。 If anyone could help or suggest a more efficient solution I would appreciate it. 如果有人可以帮助或提出更有效的解决方案,我将不胜感激。

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. 您的两个字符被换行符替换 ,换行符在Windows上实际上由回车符和换行符组成。

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 . 最可能的解释是您使用的是Microsoft Windows,其中的换行符是两个字符:回车和换行符: \\r\\n

On Microsoft Windows a std::endl will write two characters: an \\r and an \\n . 在Microsoft Windows上, std::endl将写入两个字符: \\r\\n

The fstream object you have is a representation of the bytes on disk. 您拥有的fstream对象表示磁盘上的字节。 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. std::endl写入本地行结束序列,并发出std::flush强制写入。 Under Windows, endl produces the sequence file << '\\r' << '\\n' << std::flush; 在Windows下, endl产生序列file << '\\r' << '\\n' << std::flush;

The stream position is where the 'a' is, not where the ';' 流的位置是'a'位置,而不是“;”的位置 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' . 是-通过读取该字符,您将流位置向前移了过去,因此它在'a'写了'\\r' '\\n' ,在'm'写了'\\n' '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                        ^

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM