这个问题困扰了我一晚。谢谢!
此代码会将文件的最后一行写入两次.WHY?
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
const int strSize = 1000;
int main(int argc,char *argv[])
{
ifstream infile(argv[1]);
if(!infile) cerr<<"infile error!"<<endl;
ofstream outfile(argv[2]);
int sequenceNum = 1;
char str[strSize];
while(infile){
infile.getline(str,strSize);
if(sequenceNum>469)
str[0] = '2';
else if(sequenceNum>67)
str[0] = '4';
else if(sequenceNum>1)
str[0] = '1';
else
str[0] = '3';
outfile<<str<<endl;
++sequenceNum;
}
return 0;
}
infile.getline(str,strSize);
后str
为NULL
,如果未修改str,为什么为null?但在if(sequenceNum>469)
之后,str
成为最后一行。
此代码只写一行最后一行。
#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;
const int strSize = 1000;
int main(int argc,char *argv[])
{
ifstream infile(argv[1]);
if(!infile) cerr<<"infile error!"<<endl;
ofstream outfile(argv[2]);
int sequenceNum = 1;
char str[strSize];
while(infile){
infile.getline(str,strSize);
if(strlen(str) != 0){//The key is this sentence.
if(sequenceNum>469)
str[0] = '2';
else if(sequenceNum>67)
str[0] = '4';
else if(sequenceNum>1)
str[0] = '1';
else
str[0] = '3';
outfile<<str<<endl;
++sequenceNum;
}
}
return 0;
}
答案 0 :(得分:9)
问题是当infile.getline
读取最后一行时(即直到EOF读取),while(infile)
仍将评估为true,从而导致循环再次运行。但是,由于infile
已读取整个文件,infile.getline
将失败,str
将变为空字符串。但是,由于您的原始代码会覆盖第一个字符,因此它会删除null终止符,因此最终会重复使用上一次的内容。
相反,你需要类似的东西:
while (infile.getline(str, strSize)) {
if (sequenceNum>469)
...
}
答案 1 :(得分:2)
问题是,在您阅读完最后一行后,infile
仍会评估为true
。只有在您尝试(并且失败)读取另一行后,它才会评估为false;你的for
循环进行了test-read-print,因此在退出之前无法读取并打印str
的旧内容。
请改为尝试:
while(infile.getline(str,strSize))
...
答案 2 :(得分:0)
是的,它有帮助
while(infile.getline(str,strSize))
...
答案 3 :(得分:-1)
从我看到的描述中,看到它在到达行终止符之前到达文件末尾时,eofbit
被设置。它没有说明在这种情况下输出字符串的状态是什么,因此可能的实现是它可能不被修改。
因此,在这种情况下,如果您不检查eof并且只打印字符串,它可能仍然具有上一次调用后的内容。
您在流上进行的检查不是“我在文件末尾吗?”,而是“流是否仍处于有效状态?”只有当它击中EOF然后你再次尝试从中读取它时它才会失效。
所以你可以通过检查infile.eof()
来避免双线。不幸的是,你仍然失去了最后一行的内容。据我所知,解决这个问题的唯一方法就是坚持要求任何人不要在最后一行放置任何重要字符,要么不要使用getline()
作为输入阅读。