Как вы читаете текстовый файл в вектор в c ++? - PullRequest
0 голосов
/ 05 мая 2020

Я пытаюсь прочитать текстовый файл, содержащий 9 строк отдельных целых чисел, в вектор. VS Code не возвращает синтаксической ошибки, но когда я отлаживаю программу, я получил ошибку сегментации в main (я прокомментировал строку specifici c). Я что-то не так делаю со своей реализацией? Заранее спасибо!

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
using namespace std;
vector <int> list = {};

int count_line(){   //Count the number of accounts in the txt file
    int count = 0;
    string line;
    ifstream count_file;
    count_file.open("text.txt"); //The text file simply have 9 lines of single integers in it
    if (!count_file){
        cerr<<"Problem reading from file"<<endl;
        return 1;
    }
    while (!count_file.eof()){
        getline(count_file,line);
        count ++;
    }
    count_file.close();
    return count - 1;
}

int main(){
    int i{0};
    count_line();
    ifstream input {"text.txt"};
    if (!input){
        cout<<"Problem reading from file"<<endl;
        return 1;
    }
    while (i <= count_line() && count_line() > 0){
        input>>list[i]; //I am getting a segmentation fault error here
        i++;
    }
    for (int k = 0; k < 9 ; k++){
        cout<<list[k];
    }
}

Ответы [ 2 ]

0 голосов
/ 05 мая 2020

Этот вектор:

vector <int> list = {};

Имеет ровно ноль элементов. Вы никогда не пытаетесь увеличить его размер, поэтому любой доступ к этому массиву приведет к плохому результату.

Есть несколько мест, где вы обращаетесь к этому вектору: доступ к списку.

Чтобы устранить проблему, вы можете прочитать данные в значение и затем добавить их в вектор:

int value;
input >> value;
list.emplace_back(value); // emplace back expands the vector by one place.

Но это не единственная ваша проблема:

 while (i <= count_line() && count_line() > 0){

Этот оператор while содержит вызовы, которые открывают файл, анализируют весь файл и возвращают счетчик. Я сомневаюсь, что компилятор может оптимизировать это, так что это чрезвычайно затратный вызов.

Можете ли вы просто читать значения, пока не останется ни одного? :

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

 int main()
 {
     std::ifstream     file("text.txt");
     std::vector<int>  data(std::istream_iterator<int>{file},
                            std::istream_iterator<int>{});

     for(auto val: data) {
         std::cout << val << " ";
     }
     std::cout << "\n";
 }
0 голосов
/ 05 мая 2020

Вы должны выделить элементы перед их использованием.

одно из исправлений:

    while (i <= count_line() && count_line() > 0){
        if (list.size() <= (size_t)i) list.resize(i + 1); // add this
        input>>list[i];
...