【问题标题】:Read file and input into vector读取文件并输入向量
【发布时间】:2020-11-05 05:41:59
【问题描述】:

给定一个具有以下固定内容的文本文件(只有两行,仅此而已):

43 65 123 13 41
83 67 22

我需要把它变成一个向量数组,我可以在其中应用 name.size() 来找出数组的长度,并将其中的整数用于其他目的。

结果应该是:

Array 1: 43 65 123 13 41
Array 2: 83 67 22

Array 1 Length: 5
Array 2 Length: 3

我已成功读取文本文件并使用 .push_back() 添加内容。但是,当我计算向量 .size() 时,它返回 2,我意识到它将每一行视为数组中的一个元素。

解决这个问题的方法是什么?

编辑:

添加了sn-p的代码:

vector <string> readFile(const string& fileName)
{
    ifstream source;
    source.open(filename);
    vector <string> lines;
    string line;

    while(getline(source, line)
    {
        lines.push_back(line);
    } return lines;
}

int main(int argc, char ** argv)
{
    string inputFile(argv[1]);
    vector <string> fileData = readFile(inputFile);
    
    // Check vector
    for(auto i : fileData)
        cout << i << endl;

    // Check vector length
    cout << fileData.size() << endl;
}

【问题讨论】:

  • 请以minimal reproducible example 的形式包含您的尝试。如果文件的内容总是两行,为什么不使用固定大小的向量数组来代替,例如std::array&lt;std::vector&lt;int&gt;, 2&gt;?
  • 这可以通过std::getlinestd::istringstream来完成
  • 如上。这个任务有两个部分,首先读取每一行,然后从每一行读取每个整数。你写的代码能做到这一点吗?很难说,因为你还没有发布你的代码。始终发布您的代码。
  • 在互联网上搜索“c++ 读取文件空间分隔的整数”。 StackOverflow 上已经有太多类似的问题了。
  • 恕我直言,您最好的方法是将一行作为文本读取,使用std::istringstream 将数字提取到向量中。将此向量分配给外部向量。

标签: c++ arrays vector


【解决方案1】:

如前所述,std::getlinestd::istringstream 是很好的起点。

然后您可以使用std::istream_iterator 直接使用the std::vector constructor 的迭代器重载创建向量。

大概是这样的:

std::vector<std::vector<int>> read_file(std::istream& input)
{
    std::vector<std::vector<int>> lines;

    std::string line;
    while (std::getline(input, line))
    {
        std::istringstream line_stream(line);

        lines.emplace_back(std::istream_iterator<int>(line_stream),
                           std::istream_iterator<int>());
    }

    return lines;
}

这处理包含任意数量整数值的任意数量的行。


可以这样使用:

int main(int, char* argv[])
{
    std::ifstream input(argv[1]);
    auto data = read_file(input);

    std::cout << "First line of data: ";
    for (auto value : data[0])
    {
        std::cout << value << ' ';
    }
    std::cout << '\n';

    std::cout << "Second line of data: ";
    for (auto value : data[1])
    {
        std::cout << value << ' ';
    }
    std::cout << '\n';
}

重要提示:上面的示例缺少任何类型的错误或范围检查。留给读者作为练习。

【讨论】:

  • 嗨,谢谢,我正在尝试代码,但不太确定应该如何在我的主函数中调用它?向量 fileData = read_file(inputFile);似乎不起作用,因为它说它的引用类型初始化无效
  • @user3118602 添加了与您的数据相关的如何使用它的示例。
  • @user3118602 关于错误,我的函数的返回类型是什么? fileData 变量的类型是什么?
  • 谢谢。我想我设法使用修改后的方法使其工作,并从您的回答中得到一些参考。我会将其标记为答案,因为它帮助我找到了解决方案! C++ 是一场噩梦! T_T
【解决方案2】:

您可以将每一行读为文本行,然后从文本中提取数字。

std::vector<std::vector<int>> database;
std::string text_line;
while (std::getline(cin, text_line))
{
  std::vector<int> numbers_row;
  std::istringstream number_stream(text_line);
  int value;
  while (number_stream >> value)
  {
      numbers_row.push_back(value);
  }
  database.push_back(numbers_row);
}

内部循环根据该文本行中的数字创建一个向量。
外层循环创建向量并将它们附加到数据库中。

【讨论】:

    【解决方案3】:

    常见的方法是使用std::getline 逐行读取,将其放入std::istringstream,然后使用来自该流的格式化输入——但你已经得到了答案,所以我会抛出在替代方案中。

    这使用直接来自ifstream(或任何istream 后代)和peek()s 的格式化输入来查看换行符(\n)是否是下一个字符。

    它可能看起来像这样:

    #include <istream>
    #include <vector>
    
    std::vector<std::vector<int>> read_stream(std::istream& is) {
        std::vector<std::vector<int>> res;
        std::vector<int> cur;
        int x;
    
        while(true) {
            if(is.peek() == '\n') {
                // save what we've gotten on the current line
                res.emplace_back(std::move(cur));
                cur.clear();
            }
    
            if(is >> x) cur.push_back(x);
            else break;
        }
    
        return res;
    }
    

    【讨论】:

      猜你喜欢
      • 2018-08-07
      • 2015-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-17
      • 2022-10-23
      相关资源
      最近更新 更多