【问题标题】:sprintf buffer issue, wrong assignment to char arraysprintf 缓冲区问题,错误分配给 char 数组
【发布时间】:2018-12-30 12:15:58
【问题描述】:

我遇到了 sprintf 缓冲区的问题。 正如您在下面的代码中看到的那样,我正在使用 sprintf 将 char 数组保存到缓冲区,因此 pFile 可以检查文件夹中是否有类似名称的文件。如果找到,则将缓冲区值分配给 timecycles[numCycles],并增加 numCycles。示例:timecycles[0] = "timecyc1.dat"。它运行良好,正如您在控制台输出中看到的那样,它识别出文件夹中只有 timecyc1.dat 和 timecyc5.dat。但只要我想用 for 循环读取时间周期,两个索引的值都为“timecyc9.dat”,即使 timecycles[0] 应该是“timecyc1.dat”,timecycles1 应该是“timecyc5.dat” .第二件事是,如何编写代码使 readTimecycles() 返回 char* timecycles,我可以在主函数中使用 char* timecycles[9] = readTimecycles() 或类似的东西对其进行初始化?

Console output

#include <iostream>
#include <cstdio>

char* timecycles[9];

void readTimecycles()
{
char buffer[256];
int numCycles = 0;
FILE* pFile = NULL;

for (int i = 1; i < 10; i++)
{
    sprintf(buffer, "timecyc%d.dat", i);
    pFile = fopen(buffer, "r");

    if (pFile != NULL)
    {
        timecycles[numCycles] = buffer;
        numCycles++;
        std::cout << buffer << std::endl; //to see if the buffer is correct
    }

}
   for (int i = 0; i < numCycles; i++)
   {
    std::cout << timecycles[i] << std::endl; //here's the issue with timecyc9.dat
   }
}

int main()
{
readTimecycles();

return 0;
}

【问题讨论】:

    标签: c++


    【解决方案1】:

    有任务

    timecycles[numCycles] = buffer;
    

    你让所有指针指向相同缓冲区,因为你只有一个buffer

    由于您使用 C++ 编程,因此您可以使用 std::string 轻松解决您的问题。


    如果我将你的代码改写成更多的 C++ 风格和更少的 C 风格,它可能看起来像

    std::array<std::string, 9> readTimeCycles()
    {
        std::array<std::string, 9> timecycles;
    
        for (size_t i = 0; i < timecycles.size(); ++i)
        {
            // Format the file-name
            std::string filename = "timecyc" + std::to_string(i + 1) + ".dat";
    
            std::ifstream file(filename);
            if (file)
            {
                // File was opened okay
                timecycles[i] = filename;
            }
        }
    
        return timecycles;
    }
    

    参考资料:

    【讨论】:

      【解决方案2】:

      根本问题是您对字符串的概念与 C++ 中的“字符数组”不匹配。特别是您认为,因为您分配了timecycles[numCycles] = buffer;,所以会以某种方式复制 char 数组的字符。但是在 C++ 中,所有被复制的只是一个指针,所以timecycles 最终会得到多个指向同一个缓冲区的指针。更不用说退出readTimecycles 函数时会遇到的问题。此时,您将拥有多个指向缓冲区的指针,该缓冲区不再存在,因为当您退出 readTimecycles 函数时它会被销毁。

      解决此问题的方法是使用符合您期望的 C++ 代码。特别是 std::string 将以您期望的方式复制。以下是如何更改代码以使用 std::string

      #include <string>
      
      std::string timecycles[9];
      
      timecycles[numCycles] = buffer; // now this really does copy a string
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-02
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        相关资源
        最近更新 更多