c++ - 将 char 数组的数组传递给函数

标签 c++ arrays function pointers char

在我的程序中,我可能需要加载一个大文件,但并非总是如此。所以我定义了:

char** largefilecontents;
string fileName="large.txt";

当我需要加载文件时,程序调用这个函数:

bool isitok=LoadLargeFile(fileName,largefilecontents);

函数是:

bool LoadLargeFile(string &filename, char ** &lines)
{
    if (lines) delete [] lines;
    ifstream largeFile;
    #ifdef LINUX
    largeFile.open(filename.c_str());
    #endif
    #ifdef WINDOWS
    largeFile.open(filename.c_str(),ios::binary);
    #endif      
    if (!largeFile.is_open()) return false;
    lines=new char *[10000];
    if (!lines) return false;
    largeFile.clear();
    largeFile.seekg(ios::beg);
    for (int i=0; i>-1; i++)
    {
        string line="";
        getline(largeFile,line);
        if (largeFile.tellg()==-1) break; //when end of file is reached, tellg returns -1
        lines[i]=new char[line.length()];
        lines[i]=const_cast<char*>(line.c_str());
        cout << lines[i] << endl; //debug output
    }

    return true;
}

当我查看此函数的调试输出“cout << lines[i] << endl;”时,一切正常。但是当我像这样在主程序中检查它时,一切都搞砸了:

for (i=0; i<10000; i++)
  cout << largefilecontents[i] << endl;

所以在函数 LoadLargeFile() 中,结果很好,但是没有 LoadLargeFile(),结果就乱七八糟了。我的猜测是函数的 char ** &lines 部分不正确,但我不知道这应该是什么。

有人可以帮助我吗?提前致谢!

最佳答案

问题出在您使用 line.c_str 的地方。您首先使用 lines[i]=new char[line.length()]; 为新字符串分配内存,然后覆盖 line[i] 中的指针> 使用指向局部变量 line 中的 c_str 的指针。当 line 超出范围时,此 c_str 将被销毁。您需要做的是使用 strcpy 而不是简单的指针赋值。

尝试以下操作

lines[i]=new char[line.length()+1]; //Thanks @Claptrap for the catch
strncpy(lines[i], line.c_str(), line.length()+1); //Note, strcpy is not considered safe.
                                                  //Use strncpy

如果您想严格遵守 C++ 方式,那么我建议您使用 @christian-hackl 的建议

std::vector<std::string> largefilecontents; //Since in your case 10000 is fixed
...
    bool LoadLargeFile(string &filename, std::vector<std::string> &lines)
    {
    ...
    //lines=new char *[10000];
    //if (!lines) return false;
    lines.resize(10000); //Since in your case 10000 is fixed
    ...
    for...
        if(i >= lines.size()) break; //safety net in case more than 10000 lines
        lines[i]="";
        getline(largeFile,lines[i]);
        if (largeFile.tellg()==-1) break; //when end of file is reached, tellg returns -1
        //lines[i]=new char[line.length()];
        //lines[i]=const_cast<char*>(line.c_str());

旁注:数组 v/s vector

数组是原始的 C++ 数据类型,而 vector 是类,是标准模板库的一部分。这意味着理论上 vector 比数组慢。但在实践中,速度的下降可以忽略不计。 vector 以可忽略的成本提供了两个巨大的好处

  • 内存管理。您不必删除内存,一旦 vector 对象超出范围,分配的内存就会被删除。在您的示例中,您似乎不一定需要它,因为在一般情况下您的数组永远不会被销毁
  • 灵 active 。对于数组,您必须预先知道预期的大小。而 vector 根据需要扩展。同样,您不一定需要它,因为正如您所说, vector 大小是固定的。

有两个与 vector 相关的成本

  • 性能: vector 可能比对数组的操作稍慢,但由于大多数(如果不是全部)操作被描述为内联函数,编译器开始优化它,并使它或多或少成为像数组一样高效。对于固定大小的 vector 尤其如此。
  • 内存:Vector 是一个内部使用数组的容器,这意味着 Vector 对象会有轻微的内存开销。但是将其与您可能会节省的费用进行比较,但不分配一个巨大的数组,而是逐渐扩展 vector 。仅当您创建大量小 vector 时, vector 的内存开销才可能是一个问题。在您的情况下,这种开销微不足道。

引用资料:

  1. array vs vector vs list
  2. C++ STL vector vs array in the real world
  3. http://www.cplusplus.com/forum/beginner/6321/
  4. http://www.cprogramming.com/tutorial/stl/vector.html

关于c++ - 将 char 数组的数组传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23898593/

相关文章:

c++ - OpenCV 3.0 无法加载神经网络

javascript - 在匹配正则表达式中获取多行

python - Lambda 函数 - 参数数量未知

mysql - 使用 COUNT 聚合创建 MySQL View

c - C 中检查文件是否存在特定扩展名或模式的函数

c++ - 从整数中检索最后 6 位

c++ - 如何正确存储中文字符串?

c++ - 通过转发构造函数参数构建基于可变参数模板的mixin

C - 字符串数组(二维数组)和内存分配给我带来了不需要的字符

arrays - 更改数组中变量的值