【问题标题】:use of const char * in arrays for reading sequential files在数组中使用 const char * 来读取顺序文件
【发布时间】:2012-03-17 04:21:48
【问题描述】:

抱歉,如果这是一个基本问题,但我无法从其他帖子中弄清楚。我正在尝试读取一堆标记为"1.jpg""2.jpg""3.jpg" 等的图像。我想使用for 循环来这样做。文件阅读器(我在这里使用 SOIL,正如我正在关注的 OpenGL nehe 教程中所推荐的那样),需要 const char* 作为文件名输入。

char numbers[6] = "123456"; 

for (int i=0;i<6;i++)
{
   const char* filestring = new char[5];
   *filestring = numbers[i] + ".jpg";

   texture[i] = SOIL_load_OGL_texture(filestring, ...
   ...  // filestring should be const char* form
}

错误是:

(1) 错误:字符数组的初始化字符串太长 [-fpermissive]

但我看不出char numbers[6] = "123456" 有什么问题?

错误:分配只读位置 '* filestring'

错误:从 'const char*' 到 'char' 的无效转换 [-fpermissive]

我有点困惑。将不胜感激任何建议!

谢谢。

【问题讨论】:

    标签: c++ pointers char constants


    【解决方案1】:

    改变这个:

    char numbers[6] = "123456";
    

    到这里:

    const char numbers[] = "123456";
    

    数组的大小由编译器自动确定,因此您无需显式指定它。无论如何,您都试图将它设置得太小,因为它实际上是 7 个字节宽,因为尾随 null terminator

    const 不是绝对必要的,但如果您将其标记为这样,它会更清楚您的意图。

    另外,这也行不通:

    *filestring = numbers[i] + ".jpg";
    

    您不能以这种方式连接 C 字符串。最简单的做法是:

    string filestring = string(1, numbers[i]) + ".jpg";
    

    当您需要将其用作 C 字符串时,您可以这样做:

    SOIL_load_OGL_texture(filestring.c_str(), ...
    

    【讨论】:

    • 你可能想向他解释为什么这是问题所在。
    • “因为它位于只读区域”......不,它没有。阅读stackoverflow.com/questions/7082786/char-array-vs-char
    • Re“你的字符串文字需要声明const”:仅当变量是指针时。在这里,它是一个通过复制字符串文字初始化的本地数组,因此不需要是const。虽然在这种情况下可能应该是const char *
    • 感谢大家的有用解释和一系列解决方案!非常感谢
    【解决方案2】:

    我看不出char numbers[6] = "123456" 有什么问题

    这样写:

    char numbers[6] = { '1', '2', '3', '4', '5', '6', 0 };
    

    这完全一样。你现在看到问题了吗?


    numbers[i] + ".jpg"

    这不是字符串连接。事实上,由于numbers[i] == 0x31 + i(对于 i = 0 到 5),这给出了

    &(".jpg"[49 + i])
    

    这是一个指向字符串文字末尾地址的指针。

    在 C 中,sprintf 在这里很有用,但请记住为终止的 NUL 留出空间。在 C++ 中,使用 std::string

    更好的版本:

    char filestring[] = "n.jpg";
    for( int i = 0; i < 6; i++ ) {
        filestring[0] = '1' + i;
        texture[i] = //...
    }
    

    【讨论】:

      【解决方案3】:
      std::string numbers [count] = { "1", "2", "3", ... }
      for (int i = 0; i < count; ++i) {
        std::string filename = numbers[i] + ".jpg";
        texture[i] = SOIL_load_OGL_texture(filename, ...
        //or
        //texture[i] = SOIL_load_OGL_texture(filename.c_str(), ...
      }
      

      【讨论】:

        【解决方案4】:

        这样做会更干净:

        for(int i = 0; i < 6; i ++)
        {
            char filename[8];
            sprintf(filename, "%d.jpg", i + 1);
            texture[i] = SOIL_load_OGL_texture(filename, ... 
        

        【讨论】:

          【解决方案5】:

          使用 ostringstream:

          #include <sstream>
          ...
          ...
          for (int i = 0; i < 6; i++)
          {
            std::ostringstream ss;
            ss << i << ".jpg";
          
            texture[i] = SOIL_load_OGL_texture(ss.str().c_str(), ...
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-10-23
            • 1970-01-01
            • 2011-02-27
            • 1970-01-01
            • 2015-07-07
            • 2013-12-21
            • 2017-08-09
            • 1970-01-01
            相关资源
            最近更新 更多