【问题标题】:Putting an std::string into a char[][] array将 std::string 放入 char[][] 数组
【发布时间】:2012-03-03 09:53:56
【问题描述】:

所以我正在尝试创建一个 Befunge 解释器并将一个文本文件读入一个数组。 我正在使用此代码:

char map[100][100]; //not 85 x 20
//load the source
ifstream f;
f.open("file.txt", ios::in);
string s;
int i = 0;
while(f.good() && i < 100)
{
    getline(f, s);
    map[i] = s.c_str();
    i++;
}

这不行,有谁知道不用手动循环字符串的方法吗?

【问题讨论】:

  • 但是你明白为什么它不起作用吗?这很重要……
  • 使用strcpy 并注意缓冲区溢出。您不能分配给数组。或者更好的是,使用 std::vector&lt;std::string&gt; 而不是古怪的 C 字符串
  • 有什么理由不能使用std::vector&lt;std::string&gt; 甚至std::string[100]?如果您使用的是 C++,请利用它的类型!
  • 向量可能是最好的主意,因为我正在计划无限存储,是的@ildjarn 我知道它为什么不起作用。

标签: c++ string file-io multidimensional-array


【解决方案1】:

使用strncpy()并指定字节数:

strncpy(map[i], s.c_str(), 100);
map[i][99] = '\0'; /* this could trim s.c_str(), but at least you don't get an overflow */

代替:

map[i] = s.c_str();

通过将最多复制的字节数指定为100,您可以确保不会溢出map[i]。如果strlen(s.c_str()) &lt; 100strncpy() 函数将用终止符填充map[i]。在strlen(s.c_str()) &gt;= 100 的情况下,字符串将被截断,以便为map[i] 提供必要的空终止符。

【讨论】:

  • 这可行,但我将使用 std::vector<:string> 因为我不需要存储限制。不过还是谢谢。
  • 使用 vectorstring 绝对是最惯用的 C++ 方法,而且您不必处理行长问题(至少取决于系统内存,或多或少) .
【解决方案2】:

我认为这样做更安全

char* map[100];
....   

while(f.good() && i < 100)
{
    getline(f, s);
    map[i] = new char[s.length() + 1];
    strcpy (map[i], s.c_str());
    i++;
}

【讨论】:

  • 为了安全起见,您可能需要测试map[i] = ... 的结果,以确保在strcpy() 之前确实有可用空间。
  • 我说的是“更安全”,而不是“最安全的”)))) 我给出了一个想法和方向,而不是一个现成的代码
【解决方案3】:

与此处已发布的其他答案相反,您不应尝试使用 strcpy 复制到“地图”中。 在进行任何复制之前,您要确保不会超出缓冲区。为此,您不应使用源的大小,而应使用目标的大小。原因是源可能比目标的空间长。为了避免在您完成其他操作之前可能不会出现的问题 密集计算,您应该确保不要尝试复制到一个不足以包含您尝试复制到其中的内容的目标。

这是复制字符串的函数签名(嗯,你应该在这里使用):

strncpy(dest, source, size);

以下是您应该改用的:

strncpy(map[i], s.c_str(), sizeof(map[i]));

编辑:

或者,您可以使用 strncpy_s()(如果您在 Windows 上!),它允许您指定源和目标长度。

strncpy_s(dest, dest_size, source, source_size)

【讨论】:

    猜你喜欢
    • 2015-12-23
    • 2011-10-26
    • 2012-09-03
    • 2012-11-04
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 2013-08-26
    相关资源
    最近更新 更多