我在使用课程时生气,并且正在努力使用它们。我遇到了一个问题,我试图使用一个简单的程序从一个包含简单数字的文件中检索数据(在这种情况下,#34; 1234")。
#include <iostream>
#include <fstream>
class hold
{
public:
void enter();
hold();
private:
char x[50];
};
hold::hold()
{
x[50] = NULL;
}
void hold::enter()
{
std::ifstream inFile;
inFile.open("num.txt");
int pos = 0;
while(inFile.good())
{
inFile >> x[pos];
pos++;
}
std::cout << "strlen(x) = " << strlen(x) << std::endl;
for(int i = 0; i < strlen(x); i++)
{
std::cout << x[i] << " ";
}
std::cout << std::endl;
}
int main()
{
hold h;
h.enter();
system("pause");
return 0;
}
输出结果为:
strlen(x) = 50;
1 2 3 4 (following a bunch of signs I do not know how to print).
我已经差不多一年了,因为我一直在练习课程,而且我不记得在课堂上使用过字符数组。任何人都可以告诉我,在&#34; 4&#34;之后,我弄乱了这个文件并没有终止。如果&#34; x [pos] ==&#39; \ 0&#39;我已尝试使用if语句打破while循环,但它也没有工作。
答案 0 :(得分:1)
您没有终止字符串并且您有未定义的行为,因为strlen
正在击中从未初始化的数组元素。试试这个:
while( pos < 49 && inFile >> x[pos] )
{
pos++;
}
x[pos] = '\0';
请注意,循环后的pos
现在与strlen(x)
返回的内容相同。
如果您不需要以空字符结尾的字符串,那么只需使用pos
而不是strlen(x)
而不终止,但在这种情况下,您将需要避免使用任何依赖的字符串函数以null结尾的字符串。
您的构造函数中也存在堆栈粉碎问题(未定义的行为):
hold::hold()
{
x[50] = NULL;
}
这不行。您不能修改超出数组末尾的内存。如果你想把它归零,你可以做到
memset( x, 0, sizeof(x) );
或者在C ++ 11中:
hold::hold()
: x{ 0 }
{
}
答案 1 :(得分:1)
strlen
期望以null结尾的字符串。由于您的x
不以空值终止,因此将其传递给strlen
为undefined behavior。
幸运的是,您无需致电strlen
,因为您的变量pos
会计算x
内的有效条目数:
std::cout << "length of my string = " << pos << std::endl;
for(int i = 0; i < pos ; i++) {
std::cout << x[i] << " ";
}
有没有办法解释
pos-1
以外的额外字符?
是的,更好的方法是仅在您知道字符输入成功时才增加pos
:
while(inFile >> x[pos]) {
pos++;
}