【问题标题】:Char* Constant From Previous Line Being Added Into Char* Array将上一行的 Char* 常量添加到 Char* 数组中
【发布时间】:2018-10-22 11:31:22
【问题描述】:

当我在处理一个小头文件时,我遇到了一些奇怪的事情。基本上,我声明了一个 char* 变量“文件”。在下一行,我创建了一个带有几个设置值的 char*[] 数组。但是,每次我对此进行测试时,“file”中的“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

是的,我确实在循环中使用了一个设定值(“4”)。没关系,但我使用了一个设置值,因为“sizeof(data)”正在崩溃。

(同时忽略“文件”变量名...这段代码实际上与文件写入没有任何关系。)

编译时,我得到

main.cpp: In function 'int main()':
main.cpp:5:18: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     char* file = "test.txt";
                  ^

...虽然这不会有太大影响。

将类型更改为“const char*”甚至“string”都不起作用。

有谁知道如何解决这个问题?还是只有我?

【问题讨论】:

  • 您正在读取数组的末尾。这是未定义的行为。它本可以做任何事情。在您的情况下,它找到了 file 的内容。
  • 你可以使用sizeof data / sizeof *data。或值3

标签: c++


【解决方案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.s. 你的 for 循环越界了)

【讨论】:

  • 其实这个好像不行。但是,即使循环越界,为什么它会抓取“文件”的值呢?它与“data[]”数组完全无关,至少应该是。
【解决方案2】:

字符串文字(如上面的"test.txt")是一个常量指针,但您将它分配给一个非常量指针(char *file)。相反,请尝试将 file 声明为数组类型:

char file[] = "test.txt";

【讨论】:

  • @Sergix,这充其量只能掩盖你的错误。您仍在访问越界数据。
  • @SidS 是的,我知道。不过感谢您的提醒。 :) 如果你问我,这是一个非常奇怪的错误......我想这是有道理的,但对于它为什么抓住那个变量仍然很奇怪。
【解决方案3】:

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 谢谢!那是一些奇怪的指针算法......如果你不介意你能快速解释一下它为什么有效吗?
【解决方案4】:

当您像在此处所做的那样创建简单变量时,它们通常会彼此相邻地存储在内存中。在数组的情况下,这几乎是肯定的。 例如看这段代码:

#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] 会访问下一个块中的数据。因此,无法准确预测输出,它只是随机的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 1970-01-01
    相关资源
    最近更新 更多