为什么此文件名参数是char指针而不是字符串?

时间:2018-12-16 21:44:14

标签: c++ c++14

我的uni提供了一个应该在文件中读取的功能。在参数中,有fileName参数。我不明白的是为什么他们使用字符指针而不是简单的字符串?

还有,那我怎么用字符串文件名来调用这个函数呢?

我正在Visual Studio 2017社区版上运行C ++ 14。

double* read_text(char *fileName, int sizeR, int sizeC)
{
    double* data = new double[sizeR*sizeC];
    int i = 0;
    ifstream myfile(fileName);
    if (myfile.is_open())
    {

        while (myfile.good())
        {
            if (i > sizeR*sizeC - 1) break;
            myfile >> *(data + i);
            i++;
        }
        myfile.close();
    }
    else cout << "Unable to open file";
    //cout << i;
    return data;
}

编辑:我明白了,这很愚蠢。然后,我将发布一个单独的问题。感谢您的快速回复!

1 个答案:

答案 0 :(得分:4)

  

为什么此文件名参数是char指针而不是字符串?

因为API的设计者选择这样做。 Stack Overflow的大多数人都不是该API的作者,因此我们无法准确回答此问题。

但是,我们可以回答另一个类似的问题:使用字符指针作为字符串参数的原因是什么?让我回答这个问题:

  • 不使用std::string作为参数将允许API用户不创建std::string对象。在以下情况下,这可能会很有用:
    • 该API需要用于不提供标准库且因此没有std::string的“独立式”实现中。这可能不适用于您的特定示例,因为该函数的实现使用标准库,但出于完整性考虑,我加入了此参数。
    • 该API需要在std::string不提供动态内存分配的系统上使用。
    • 在使用API​​的情况下,创建字符串可能需要的动态内存分配可能太慢了(这不适用于将要从磁盘读取的API,但是我在这里包括了完整性)。
  • ({constchar*使得可以使用C语言的API。这可能是相关的,因为:
    • 该API最初可能是为C编写的,已被继承到现在使用C ++的代码库中,但是为了保持向后兼容性,尚未更改该API。
    • 提供与C兼容的API,可以使用其他能够与C进行接口的语言的API。许多语言都支持C接口,而很少有语言支持C ++接口。
  

还有,那我怎么用字符串文件名来调用这个函数呢?

您可以使用c_str成员函数获得指向以空终止的字符串的指针。不幸的是,API设计不良,参数是非常量,而c_str返回的指针是const。您可以const_cast参数的常数,以调用此函数。这是“确定”,因为该函数实际上并未修改指向的字符串。

如果您可以要求C ++ 17标准并且源字符串为非常量,则data成员函数将更加简单,因为它不需要const_cast。在C ++ 17之前,没有非const重载,因此它需要相同的const强制转换,并且在C ++ 11之前,不能保证指向的字符串以null结尾。

明确说明:此函数使用非常量字符串参数是错误的设计-无论该参数是指向以null结尾的字符串的字符指针,还是指向std::string的引用。


P.S。还有其他更严重的问题:

  • 函数的调用者可能无法知道从文件中读取了多少个数字。如果文件的值小于sizeR*sizeC,则无法避免UB。
  • 返回拥有动态内存资源的裸指针是一个非常糟糕的设计。
  • 从文件读取的循环检查之后是否成功读取了该值,该值已添加到数组中并且该值从未被覆盖,因此写入数组中的最后一个元素始终是值未指定。