【问题标题】:How to read a file into vector in C++?如何在 C++ 中将文件读入向量?
【发布时间】:2013-02-28 15:03:16
【问题描述】:

我需要从每行包含一个新的float 数字的.data.txt 文件读取到一个向量中。

我进行了广泛的搜索并应用了许多不同的方法,但每次我得到相同的结果时,Main.size()0 和错误说 "Vector Subscript out of Range",所以很明显向量只是没有读入任何内容文件。

注意:该文件既在文件夹中,也包含在 VS 项目中。

无论如何,这是我的代码:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

int main() {

    vector<double> Main;
    int count;
    string lineData;
    double tmp;

    ifstream myfile ("test.data", ios::in);

    double number;  

    myfile >> count;
    for(int i = 0; i < count; i++) {
        myfile >> tmp;
        Main.push_back(tmp);
        cout << count;
    }

    cout << "Numbers:\n";
    cout << Main.size();
    for (int i=0; i=((Main.size())-1); i++) {
        cout << Main[i] << '\n';
    }

    cin.get(); 
    return 0;
}

我得到的结果总是很简单:

Numbers:
0

【问题讨论】:

  • 检查所有I/O操作的结果。
  • 你的test.data实际上是什么样子的?
  • 请查看反序列化。通常你会创建一个向量类和一个向量集合类(可以处理 txt 输入文件)。一个好的开始是这个问题的答案:stackoverflow.com/questions/11415850/…
  • test.data 就像这样:1.4049 4.9166 3.3903 2.4963 2.4429 3.7053 1.9727 3.1569 2.5528 4.4527 1.5241 但有 1000 个条目都在新行上
  • How to read a binary file into a vector of unsigned chars 的可能重复项。看起来在您询问之前 20 分钟询问了 dup。你们上的是同一门课吗?

标签: c++ vector file-io


【解决方案1】:

你的循环是错误的:

for (int i=0; i=((Main.size())-1); i++) {

试试这个:

for (int i=0; i < Main.size(); i++) {

此外,将数字读入向量并将其写入标准输出的更惯用方式是这样的:

#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <algorithm> // for std::copy

int main()
{
  std::ifstream is("numbers.txt");
  std::istream_iterator<double> start(is), end;
  std::vector<double> numbers(start, end);
  std::cout << "Read " << numbers.size() << " numbers" << std::endl;

  // print the numbers to stdout
  std::cout << "numbers read in:\n";
  std::copy(numbers.begin(), numbers.end(), 
            std::ostream_iterator<double>(std::cout, " "));
  std::cout << std::endl;

}

尽管您应该检查ifstream 的状态以了解读取错误。

【讨论】:

  • 然后就可以了。隐藏的分配错误。谢谢,C!
  • 好的,这很好用,但现在看来问题是它没有找到文件或将文件读取为空白。
  • @Orgmo 我添加了一些代码,显示了一种打印向量内容的方法。与循环相比,它没有太多优势,但它展示了另一个 C++ 习惯用法。
【解决方案2】:

只是稍微扩展一下 juanchopanza 的答案...

for (int i=0; i=((Main.size())-1); i++) {
    cout << Main[i] << '\n';
}

这样做:

  1. 创建i并将其设置为0
  2. i 设置为Main.size() - 1。由于Main 为空,Main.size()0i 被设置为-1
  3. Main[-1] 是越界访问。卡布姆。

【讨论】:

  • 我认为主要问题不是边界,(认为这是一个问题)。问题是赋值运算符=和比较运算符==之间的区别。
  • 这就是雪崩的开始。边界违规是实际调用错误的部分。重点是说明为什么这是一个错误。恕我直言,BASIC 做对的一件事是让赋值语句而不是表达式。因此,您不需要==:= 或任何其他虚构的运算符,并且一开始就不会犯这样的错误。
  • 同意。我看到我的同事多年来一直使用 C++ 编码,但仍然不知道赋值运算符返回一个值:)
  • 它应该返回一个引用。
  • OFC,我的意思是它返回。许多常用词已被保留,现在应该准确使用:)
【解决方案3】:

只是一个建议。 而不是写

for (int i=0; i=((Main.size())-1); i++) {
   cout << Main[i] << '\n';
}

按照上面的建议,写一个:

for (vector<double>::iterator it=Main.begin(); it!=Main.end(); it++) {
   cout << *it << '\n';
}

使用迭代器。如果你有C++11 支持,你可以将i 声明为auto i=Main.begin()(不过只是一个方便的快捷方式)

这避免了因无意中遗漏-1 而导致的讨厌的one-position-out-of-bound 错误。

【讨论】:

    【解决方案4】:

    1。 在循环中你是在赋值而不是比较值所以

    i=((Main.size())-1) -> i=(-1) 自 Main.size()

    Main[i] 将产生“向量下标超出范围”因为 i = -1。

    2。 你得到 Main.size() 为 0 可能是因为它不是它找不到文件。给出文件路径并检查输出。初始化变量也很好。

    【讨论】:

      【解决方案5】:
      #include <iostream>
      #include <fstream>
      #include <vector>
      using namespace std;
      
      int main()
      {
      fstream dataFile;
      string name , word , new_word;
      vector<string> test;
      char fileName[80];
      cout<<"Please enter the file name : ";
      cin >> fileName;
      dataFile.open(fileName);
      if(dataFile.fail())
      {
           cout<<"File can not open.\n";
           return 0;
      }
      cout<<"File opened.\n";
      cout<<"Please enter the word : ";
      cin>>word;
      cout<<"Please enter the new word : ";
      cin >> new_word;
      while (!dataFile.fail() && !dataFile.eof())
      {
            dataFile >> name;
            test.push_back(name);
      }
      dataFile.close();
      
      }
      

      【讨论】:

      • 如果您还可以在答案中添加简短评论,而不仅仅是发布代码,那就太好了。
      【解决方案6】:
        //file name must be of the form filename.yourfileExtension
             std::vector<std::string> source;
      bool getFileContent(std::string & fileName)
      {
          if (fileName.substr(fileName.find_last_of(".") + 1) =="yourfileExtension")
          {
      
              // Open the File
              std::ifstream in(fileName.c_str());
      
              // Check if object is valid
              if (!in)
              {
                  std::cerr << "Cannot open the File : " << fileName << std::endl;
                  return false;
              }
              std::string str;
              // Read the next line from File untill it reaches the end.
              while (std::getline(in, str))
              {
                  // Line contains string of length > 0 then save it in vector
                  if (str.size() > 0)
                      source.push_back(str);
              }
              /*for (size_t i = 0; i < source.size(); i++)
          {
              lexer(source[i], i);
              cout << source[i] << endl;
          }
          */
              //Close The File
              in.close();
              return true;
          }
          else
          {
              std::cerr << ":VIP doe\'s not support this file type" << std::endl;
              std::cerr << "supported extensions is filename.yourfileExtension" << endl;
          }
      }
      

      【讨论】:

      • 您好!虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释并说明适用的限制和假设。
      猜你喜欢
      • 2019-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多