我一直在玩C ++(刚刚开始),我正在尝试创建一个需要函数的程序来计算C ++中的行数。但是,我遇到了奇怪的行为,其中正常的赋值不起作用,但通过地址分配,然后立即取消引用。像这样:
int countLinesInFile(string fileName){
char c[32];
int numLines = 0;
ifstream file(fileName);
while(file >> c){
numLines += 1;
cout << "Lines: " << numLines << endl;
}
return numLines;
}
结果是:
Lines: 1
Lines: 1
Lines: 1
Lines: 1
Lines: 1
Lines: 1
但是,当我将numLines += 1
更改为*(&numLines) += 1
时,它会神奇地起作用:
Lines: 1
Lines: 2
Lines: 3
Lines: 4
Lines: 5
Lines: 6
对于一点背景,我正在阅读的文件是一个6行文件,其中每行是32位二进制字符串(等于零)。当我打印出c(带cout << c
)时,它看似正确打印出来。另外,我知道这可能不是从文件中读取行的最佳或正确方法,但除非这根本不可能有效,否则我更感兴趣的是为什么会发生这种行为的基本机制,以及我的内容我做错了。
答案 0 :(得分:1)
嗯,这是答案。正如 StoryTeller 所说,数组必须长度为33个字符才能捕获终止字符并防止异常行为。
P.S。感谢所有有用的评论,我同意getline可能是更好的选择。如果有人对这种溢出究竟是如何引起这种非常受欢迎的奇怪行为有任何见解。
答案 1 :(得分:1)
'\0'
字符二进制值为00000000
。我想numLines
就在你的数组c
之后,在内存中总是用零擦除,然后再增加1.所以它总是显示为1.
编译第二个版本时,必须以另一种方式组织内存(只有编译器知道,如果你在非常低的级别进行调试,则会这样),这不会影响numLines
值。
答案 2 :(得分:0)
将类std::string
与API std::getline
一起使用,您可以在每次读取时读取整行,并在每次读取计数器变量时增加:
std::string sLine;
std::ifstream in("main.cpp");
int nLines = 0;
while(std::getline(in, sLine))
++nLines;
std::cout << nLines << endl;
in.close();