getline вызывает ошибку сегментации в C ++? - PullRequest
0 голосов
/ 01 марта 2019

Я сейчас пытаюсь выучить C ++.Мне дают файл .txt, который содержит разные данные о людях в каждой строке.Я хочу прочитать эти данные в массив строк.Я не вижу ничего плохого в этой функции, и я делал то же самое раньше, но по какой-то причине я получаю ошибку сегментации.

#include <string>
#include <iostream>
#include <fstream>

void readFile(std::istream&, std::string*);
int lineCount(std::istream&);

int main(){
    std::ifstream inFile("input.txt");
    int numLines = lineCount(inFile);
    std::string data[numLines];
    inFile.close();
    inFile.open("input.txt");
    readFile(inFile, data);
    inFile.close();
    return 0;
}

int lineCount(std::istream& inFile){
    std::string line;
    int numLines = 0;
    while(std::getline(inFile, line)){
        numLines++;
    }
    return numLines;
}

void readFile(std::istream& inFile, std::string *data){
    int i = 0;
    while(std::getline(inFile, data[i])){
         std::cout << i << "\n"; //testing values
         std::cout << data[i] << "\n"; //testing values
         i++;
    }
}

Вот вывод приведенного выше кода.

//Output
//Note, these are fictional people
0
Florence,Forrest,1843 Glenview Drive,,Corpus Christi,TX,78401,10/12/1992,5/14/2012,3.215,127/11/1234,2.5,50
1
Casey,Roberta,3668 Thunder Road,,Palo Alto,CA,94306,2/13/1983,5/14/2014,2.978,95
2
Koch,Sandra,2707 Waterview Lane,Apt 302,Las Vegas,NM,87701,6/6/1972,12/14/2015,2.546,69
Segmentation fault //occurs in while condition

Любая помощь будет оценена

1 Ответ

0 голосов
/ 01 марта 2019

Мне плохо, что я не сразу это увидел.

int numLines = lineCount(inFile);

возвращает правильное количество строк в файле.Ошибка не здесь, человек.

std::string data[numLines];

Не кошерный C ++, но создаст массив с элементом для каждой строки в файле, если поддерживается.Ваша программа запущена, поэтому она поддерживается.Тем не менее, предпочитайте использовать Контейнеры библиотеки .

Тем временем в readFile ...

while(std::getline(inFile, data[i]))

Попытается прочитать строку в data[i].Независимо от того, успешно ли выполнено чтение, должен быть data[i] для чтения.Не будет последней попытки.

Логика будет

  1. читать в строке 1. Успешно, поэтому
  2. читать в строке 2. Успешно, поэтому
  3. прочитано в строке 3. Успешно, поэтому
  4. прочитано в строке 4. Ошибка.Но это не мешает getline не смотреть в конец data на string и на подъем (особенно неопределенное поведение , которое проявляется как идущий бум), потому что его нет.

Правильное решение

int main(){
    std::ifstream inFile("input.txt");
    // no longer need. Vector keeps track for us
    // int numLines = lineCount(inFile);
    std::vector<std::string> data;
    // read nothing from file. Don't need to rewind
    readFile(inFile, data);

    // note: files close themselves when they are destroyed.
    //inFile.close(); 
    return 0;
}
void readFile(std::istream& inFile, std::vector<std::string> & data){
    int i = 0;
    std::string line; // line to read into. Always there, so we don't have to worry.
    while(std::getline(inFile, line)){
         std::cout << i << "\n"; //testing values
         std::cout << line << "\n"; //testing values
         data.push_back(line); // stuff line into vector.
         i++;
    }
}

Нет vector Допустимое решение

int main(){
    std::ifstream inFile("input.txt");
    int numLines = lineCount(inFile);
    // legal in every C++, but prefer container may want some extra armour 
    // here to protect from numlines 0. 
    std::string * data = new std::string[numlines]; 
    // the following is a faster way to rewind a file than closing and re-opening
    inFile.clear(); // clear the EOF flag
    inFile.seekg(0, ios::beg); // rewind file.
    readFile(inFile, data);
    inFile.close();
    return 0;
}
void readFile(std::istream& inFile, std::string * data){
    int i = 0;
    std::string line; // same as above. line is here even if data[i] isn't
    while(std::getline(inFile, line)){
         std::cout << i << "\n"; //testing values
         std::cout << line << "\n"; //testing values
         data[i] = line; // stuff line into array. Smart compiler may realize it can move
                         //if not, c++11 adds a formal std::move to force it.
         i++;
    }
}
...