C++ 在读取文件时提高空间复杂性

C++ 在读取文件时提高空间复杂性,c++,readfile,space-complexity,C++,Readfile,Space Complexity,我在一个文件中有一行任意长的整数(或浮点值),用逗号分隔: 1,2,3,4,5,6,7,8,2,3,4,5,6,7,8,9,3,... (can go upto >100 MB) 现在,我必须读取这些值并将它们存储在数组中 我当前的实现如下所示: float* read_line(int dimension) { float *values = new float[dimension*dimension]; // a line will have dimension^

我在一个文件中有一行任意长的整数(或浮点值),用逗号分隔:

1,2,3,4,5,6,7,8,2,3,4,5,6,7,8,9,3,...  (can go upto >100 MB)
现在,我必须读取这些值并将它们存储在数组中

我当前的实现如下所示:

 float* read_line(int dimension)
   {
     float *values = new float[dimension*dimension]; // a line will have dimension^2 values
     std::string line;
     char *token = NULL, *buffer = NULL, *tmp = NULL;
     int count = 0;

     getline(file, line);
     buffer = new char[line.length() + 1];
     strcpy(buffer, line.c_str());
     for( token = strtok(buffer, ","); token != NULL; token = strtok(NULL, ","), count++ )
       {
         values[count] = strtod(token, &tmp);
       }
     delete buffer;
     return values;
   }
我不喜欢此实现,因为:

  • 使用
    ifstream
    将整个文件加载到内存中,并且 然后被克隆到一个
    float[]
  • 存在不必要的重复(从
    std::string
    转换为
    const char*
优化内存利用率的方法有哪些

谢谢

像这样的

float val;
while (file >> val)
{
  values[count++] = val;
  char comma;
  file >> comma; // skip comma
}
像这样的

float val;
while (file >> val)
{
  values[count++] = val;
  char comma;
  file >> comma; // skip comma
}
使用and
istreambuf_迭代器

std::vector<float> test; //Optionally call reserve to avoid frequent memory reallocation
boost::tokenizer<boost::char_separator<char>, std::istreambuf_iterator<char> > tokens(std::istreambuf_iterator<char> (in), std::istreambuf_iterator<char>(), boost::char_separator<char>(","));
//Replace this lambda by your favourite conversion function.
std::transform(tokens.begin(), tokens.end(), std::back_inserter(test), [](std::basic_string<char> s) { return atof(s.c_str()); } );
std::向量测试//可选地调用reserve以避免频繁的内存重新分配
boost::标记器标记(std::istreambuf_迭代器(in),std::istreambuf_迭代器(),boost::char_分隔符(“,”);
//用您喜爱的转换函数替换此lambda。
std::transform(tokens.begin()、tokens.end()、std::back_inserter(test),[](std::basic_string s){return atof(s.c_str());});
编辑:
test
是我用来表示
值的,除了它是
std::vector
而不是数组,数组通常是更好的选择

嗯,这个代码有一些优点。迭代器具有内置的eof处理,您可以非常轻松地扩展分隔符。它非常容易出错(特别是当您使用使用使用异常的atof替换时)。

使用and
istreambuf\u迭代器

std::vector<float> test; //Optionally call reserve to avoid frequent memory reallocation
boost::tokenizer<boost::char_separator<char>, std::istreambuf_iterator<char> > tokens(std::istreambuf_iterator<char> (in), std::istreambuf_iterator<char>(), boost::char_separator<char>(","));
//Replace this lambda by your favourite conversion function.
std::transform(tokens.begin(), tokens.end(), std::back_inserter(test), [](std::basic_string<char> s) { return atof(s.c_str()); } );
std::向量测试//可选地调用reserve以避免频繁的内存重新分配
boost::标记器标记(std::istreambuf_迭代器(in),std::istreambuf_迭代器(),boost::char_分隔符(“,”);
//用您喜爱的转换函数替换此lambda。
std::transform(tokens.begin()、tokens.end()、std::back_inserter(test),[](std::basic_string s){return atof(s.c_str());});
编辑:
test
是我用来表示
值的,除了它是
std::vector
而不是数组,数组通常是更好的选择


嗯,这个代码有一些优点。迭代器具有内置的eof处理,您可以非常轻松地扩展分隔符。它非常容易出错(特别是当您使用使用使用异常的atof替换时)。

我想尝试一些基于osgx使用scanf的建议的东西:

freopen("testcases.in", "r", stdin);
while( count < total_values)
       {
         scanf("%f,",&values[count]);
         count++;
       }
freopen(“testcases.in”,“r”,stdin);
而(计数<总值)
{
scanf(“%f,”,&value[count]);
计数++;
}

根据osgx关于使用scanf的建议,我想尝试一些东西:

freopen("testcases.in", "r", stdin);
while( count < total_values)
       {
         scanf("%f,",&values[count]);
         count++;
       }
freopen(“testcases.in”,“r”,stdin);
而(计数<总值)
{
scanf(“%f,”,&value[count]);
计数++;
}

您能用普通C读取文件吗?例如,
fscanf。。。“%f,”&值[i]
我可以。它会比@jahhaj的答案更受欢迎吗?你能用普通C读文件吗?例如,
fscanf。。。“%f,”&值[i]
我可以。它会比@jahhaj的答案更受欢迎吗?当它到达一行的末尾时,阅读会有一个问题。你知道怎么纠正吗?一旦读到一行的末尾,就有问题了。你知道怎么纠正吗?