当我处理一个小的头文件时,我遇到了一些奇怪的东西。基本上,我声明了一个char *变量"文件"。在下一行,我创建一个char * []数组,其中包含一些设置值。但是,每次我测试这个" test.txt"来自"文件"的内容被附加到" data []" ...的末尾,我没有任何线索的原因。附件是我可以获得代码的最简单的形式。
在我的文件main.cpp中:
#include <iostream>
using namespace std;
int main() {
char* file = "test.txt";
const char* data[] = {"test6", "test7", "test8"};
for (int i = 0; i < 4; i++)
{
cout << data[i];
}
return 0;
}
我只是简单地使用
进行编译g++ main.cpp
是的,我确实在循环中使用了一个设定值(&#34; 4&#34;)。这没关系,但我使用了一个设定值因为&#34; sizeof(数据)&#34;崩溃了。
(同样忽略&#34;文件&#34;变量名......这段代码与文件编写没有任何关系。)
编译时,我得到了
main.cpp: In function 'int main()':
main.cpp:5:18: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
char* file = "test.txt";
^
......虽然这不应该影响很多。
将类型更改为&#34; const char *&#34;甚至&#34;字符串&#34;不起作用。
有谁知道如何解决此问题?还是只是我?
答案 0 :(得分:2)
data
中的元素数量为3,而不是4,因此您可以访问循环中的边界数据。结果是未定义的行为。由于未定义的行为是 - 好的,未定义的 - 任何事情都可能发生。
你可以这样做:
for (int i = 0; i < sizeof data / sizeof *data; i++)
{
cout << data[i];
}
你必须进行除法的原因是sizeof data
等于data
中元素的数量(即3)乘以每个元素的大小(可能是4或8,具体取决于你的编译器)。所以你必须除以每个元素的大小。 (元素是指针,而不是字符。)
至于警告,您可以像这样声明file
:
const char *file = "test.txt";
答案 1 :(得分:1)
试试这个:
#include <iostream>
using namespace std;
int main() {
string file = "test.txt";
const char* data[] = {"test6", "test7", "test8"};
for (int i = 0; i < 3; i++)
{
cout << data[i];
}
return 0;
}
问题在于您将字符串转换为char指针。 (P.你的循环超出范围)
答案 2 :(得分:1)
字符串文字(如上面的"test.txt"
)是一个常量指针,但是您将它指定给非常量指针(char *file
)。相反,尝试将file
声明为数组类型:
char file[] = "test.txt";
答案 3 :(得分:1)
当您创建简单变量时,就像您在此处所做的那样,它们通常会彼此相邻地存储在内存中。在阵列的情况下,这几乎是确定的。 例如,请参阅此代码:
#include<iostream>
int main()
{
int i=0;
int a[] = {1,2,3};
int c = 10;
for(i=0;i<5;i++)
std::cout << a[i] << std::endl;
}
所以,这里很可能会在连续的块中分配内存,如下所示:
| a [0] - a [1] - a [2] - i - c |或
| i - a [0] - a [1] - a [2] - c |
根据具体情况,您的输出将为:1,2,3,3,10或0,1,2,3,10 现在在你的情况下发生类似的事情(虽然这个例子中使用的内存类型和你的情况不同),因为你超越了数组的边界,data [3]访问下一个块中的数据。因此,输出无法准确预测,只是随机。