【问题标题】:C++ fstream: get() skipping first and last lineC ++ fstream:get()跳过第一行和最后一行
【发布时间】:2020-06-20 22:54:25
【问题描述】:

我正在从整数文件中读取,将文件中的每个元素转换为整数并将整数添加到向量向量中,如果文件移动到新行,则向量向量将移动到新向量.例如,如果输入文件包含:

9
2 5 8
7 1 10
5 3
20 15 30
100 12

向量的向量应该包含:

[ [9],
  [2, 5, 8],
  [7, 1, 10],
  [5, 3],
  [20, 15, 30],
  [100, 12] ]

但是,我的实现的问题在于它存储:

[ [2, 5, 8],
  [7, 1, 10],
  [5, 3],
  [20, 15, 30] ]

导致代码输出:

2 5 8
7 1 10
5 3
20 15 30

代码:

#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

int main() {
    ifstream inputFile("input.txt"); // Opens input file.

    char currentChar;
    int currentInput = 0;
    vector<vector<int>> vec;
    vector<int> vec2;

    while (inputFile.get(currentChar)) { // Reads each character of given file.

        if (currentChar == '\n') { // If current character is a new line, store current vec2 in vec and clear vec2
            vec.push_back(vec2);
            vec2.clear();
        }

        inputFile >> currentInput; // Current character to integer
        vec2.push_back(currentInput); // Adds current integer to vec2

    }
    vec2.clear();
    inputFile.close();

    for (const auto& inner : vec) { // Prints vector of vectors.
        for (auto value : inner) {
            cout << value << " ";
        }
        cout << endl;
    }
}

任何有关解决此问题的方法的建议都会有很大帮助。

【问题讨论】:

  • get() 从文件中读取第一个字符。一旦读取了“9”,它就会被读取。它不见了。它不再在文件中。它不再是了。它渴望峡湾。它不再是文件中的字符。所以,后面的格式化提取操作符&gt;&gt;当然不会读取它。你不清楚这部分的哪一部分?这是一种根本错误的做法。您应该使用 std::getline 一次读取一行,再简单不过了,然后使用 &gt;&gt; 提取行中的每个 int 值,并用它来构造一个向量。这应该只有 4-5 行代码。

标签: c++ file-io fstream iostream


【解决方案1】:

我使用std::istream::getline逐行处理文件。
试试这个,

#include <iostream>

#include <string>
#include <vector>

#include <fstream>
#include <sstream>

int main(int , char *[]){

    std::ifstream stream("input.txt");
    std::istringstream other("");

    int i = 0;
    char buffer[100] = {};

    std::vector<std::vector<int>> data;
    std::vector<int> vec;

    stream.getline(buffer, 100);

    while(stream.gcount() > 1){
        other.clear();
        other.str(buffer);

        while (other >> i) {
            vec.push_back(i);
        }

        if(!vec.empty()){
            data.push_back(std::move(vec));
        }

        stream.clear();
        stream.getline(buffer, 100);
    }

    for(const auto& ele: data){
        std::cout<< "[ ";
        for(int vecEle: ele){
            std::cout<< vecEle<< " ";
        }
        std::cout<< "]\n";
    }
}

输出:

[ 9 ]
[ 2 5 8 ]
[ 7 1 10 ]
[ 5 3 ]
[ 20 15 30 ]
[ 100 12 ]

【讨论】:

  • 这是我的问题的有效解决方案。感谢您的帮助,但是,我不确定它是否严格来说更好,但由于可读性,我更喜欢我的解决方案。这种额外的解决方案可以扩大帮助范围以覆盖他人。
  • @Uz0r 欢迎您,由您决定哪种解决方案更适合您,关于我的解决方案,我只是提出解决这个问题的想法。
【解决方案2】:

通过改变 while 循环来修复它。

while (!inputFile.eof()) {

    inputFile >> currentInput;

    vec2.push_back(currentInput);

    if (inputFile.peek() == '\n' || inputFile.peek() == EOF) {
        vec.push_back(vec2);
        vec2.clear();
    }
}

我在查找下一行和文件末尾时遇到了麻烦。已通过使用 peek 函数查找“\n”和文件结尾 (EOF) 来解决此问题。

【讨论】:

    【解决方案3】:
    while (!inputFile.eof(0)) {
    
        inputFile >> currentInput;
    
        vec2.push_back(currentInput);
    
        if (inputFile.peek() == '\n') {
            vec.push_back(503);
            vec2.clear();
        }
    }
    

    【讨论】:

    • 4679\这是错字吗?
    猜你喜欢
    • 2015-06-24
    • 1970-01-01
    • 2019-04-13
    • 2014-06-07
    • 2013-08-17
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多