Getline для чтения данных из текстового файла - PullRequest
0 голосов
/ 22 мая 2018

У меня небольшая проблема с извлечением данных из простого файла .txt с помощью команды getline.

Файл txt очень прост: столбец из 400 чисел.Я использую вектор для хранения их со следующим кодом:

int i = 0;
string line;
vector <double> vec;

while (getline(input, line))
{
    vec.push_back(i);
    N++;
    input >> vec[i];
    i++;
} 

Он правильно создает вектор из 400 элементов, но первая строка файла TXT игнорируется (в итоге я получаю vec [0] = 2-я строкаTXT-файл вместо 1-го), а 399-й элемент равен 399 вместо 400-й строки TXT-файла.

Я пытался извлечь другие данные несколькими способами, но это оказалось безуспешным.

Спасибо за вашу помощь!

РЕДАКТИРОВАТЬ:

Я отредактировал код в соответствии с некоторыми замечаниями:

vector <double> vec;
string line;
double num;

while (getline(input, line))
{
    input >> num;
    vec.push_back(num);
}

К сожалению, он все еще пропускает первую строку моего текстового файла.

РЕДАКТИРОВАТЬ 2 -> РЕШЕНИЕ:

Благодаря всем вашим замечаниям я понялчто я делал что-то не так при использовании getline и input >> num;

Вот как проблема была решена:

double num;
vector <double> vec;

while (input >> num)
{
    vec.push_back(num);
}

Ответы [ 4 ]

0 голосов
/ 22 мая 2018

Вы начинаете с помещения 0 в вектор на первой итерации:

vec.push_back(i);

, затем после чтения первой строки вы читаете следующую строку, но указатель потока из файла уже находится в другом месте, поэтому вы переопределяетеэто 0 и пропустить первое значение из потока.Что еще хуже, странным образом конвертируется в двойное число:

input >> vec[i];

Таким образом, вы ошибетесь.Попробуйте это:

while (std::getline(file, line)) {
    //In c++11
    vec.emplace_back(std::stod(line));
    //In c++ 98, #include <stdlib.h> needed
    //vec.push_back(atof(line.c_str())); 
}

Предполагается, что у вас всегда будет нужный файл.

0 голосов
/ 22 мая 2018

Вы можете прочитать весь файл в вектор, просто передав std::istream_iterator в std::vector конструктор, без циклов:

std::vector<int> v{
    std::istream_iterator<int>{input}, 
    std::istream_iterator<int>{}
};

Например:

#include <iostream>
#include <iterator>
#include <vector>
#include <exception>

template<class T>
std::vector<T> parse_words_into_vector(std::istream& s) {
    std::vector<T> result{
        std::istream_iterator<T>{s},
        std::istream_iterator<T>{}
    };
    if(!s.eof())
        throw std::runtime_error("Failed to parse the entire file.");
    return result;
}

int main() {
    auto v = parse_words_into_vector<int>(std::cin);
    std::cout << v.size() << '\n';
}
0 голосов
/ 22 мая 2018

Вы теряете первую строку из-за чтения из файла еще раз - здесь:

while (getline(input, line))
    // ^^^^^^^ Here you read the first line
{
    input >> num;
 // ^^^^^^^^ Here you will read the second line

Вы сказали, что хотите получить вектор двойных чисел - как:

std::vector<double> vec;

Итак, выследует использовать std::stod, чтобы преобразовать строку, прочитанную getline, в двойную.Например:

while (std::getline(input, line))
{
    // Convert the text line (i.e. string) to a floating point number (i.e. double)
    double tmp;
    try
    {
        tmp = stod(line);
    }
    catch(std::invalid_argument)
    {
        // Illegal input
        break;
    }
    catch(std::out_of_range)
    {
        // Illegal input
        break;
    }

    vec.push_back(tmp);
} 

Не делать input >> num; внутри цикла.

Если вы действительно хотите использовать input >> num;, тогда вы не должны используйте getline.То есть - вы можете использовать оба, но , а не оба.

0 голосов
/ 22 мая 2018

Измените цикл while, как показано ниже: -

while (getline(input, line))
{
    vec.push_back(line);
    //N++;
    //input >> vec[i];
    //i++;
} 

Также попробуйте использовать параметр ниже

 do{
    vec.push_back(i);
    //N++;
    //i++;
 }while (input >> vec[i++]);
...