2016-11-18 2 views
0

Я написал функцию, которая читает неизвестное количество данных (когда в столбце) из файла в вектор.Функция чтения из файла в вектор C++

#include <iostream> 
#include <vector> 
#include <fstream> // file writing 
#include <cassert> 


void ReadFromFile(std::vector<double> &x, const std::string &file_name) 
{ 
    std::ifstream read_file(file_name); 
    assert(read_file.is_open()); 

    size_t lineCount = 0; 
    while (!read_file.eof()) 
    { 
     double temp; 
     read_file >> temp; 
     x.at(lineCount) = temp; 
     if (lineCount == x.size() - 1) { break; } // fixes the out of range exception 

     lineCount++; 
    } 
    read_file.close(); 
} 
int main() 
{ 
    size_t Nx = 7; 
    size_t Ny = 7; 
    size_t Nz = 7; 
    size_t N = Nx*Ny*Nz; 

    // Initial Arrays 
    std::vector <double> rx(N); 
    std::string Loadrx = "Loadrx.txt"; 
    ReadFromFile(rx, Loadrx); 
} 

Но lineCount увеличивает одно дополнительное время после того, как данные из файла были скопированы в вектор. Есть ли более элегантный способ решения этой проблемы, чем заявление if, которое я написал?

EDIT: Очевидно, что я не буду загружать файл данных. Код компилируется отлично. Я просто ищу улучшения в выражении if (если он существует).

+0

Используйте GetLine() вместо этого. –

+0

@Matt О чем ты говоришь? Код просто компилируется в VS15 – nikjohn

+0

Используйте x.push_back() вместо x.at (linecount), передайте N прямо в ReadFromFile, постройте v, но оставьте пустым и зарезервируйте N элементов. –

ответ

2

Я написал функцию, которая считывает неизвестного количества данных (когда в колонке) из файла в вектор.

Один из самых элегантных (и, я полагаю, идиоматические) способы чтения неизвестного количества данных из «колонок» (или иначе регулярно отформатированный файл) является использование IStream итераторов:

void ReadFromFile(std::vector<double> &x, const std::string &file_name) 
{ 
    std::ifstream read_file(file_name); 
    assert(read_file.is_open()); 

    std::copy(std::istream_iterator<double>(read_file), std::istream_iterator<double>(), 
     std::back_inserter(x)); 

    read_file.close(); 
} 

Использование:

int main() 
{ 
    // Note the default constructor - we are constructing an initially empty vector. 
    std::vector<double> rx; 
    ReadFromFile(rx, "Loadrx.txt"); 
} 

Если вы хотите, чтобы написать «безопасный» вариант с ограниченным числом элементов для чтения, используйте copy_if:

void ReadFromFile(std::vector<double> &x, const std::string &file_name, unsigned int max_read) 
{ 
    std::ifstream read_file(file_name); 
    assert(read_file.is_open()); 

    unsigned int cur = 0; 
    std::copy_if(std::istream_iterator<double>(read_file), std::istream_iterator<double>(), 
    std::back_inserter(x), [&](const double&) { 
     return (cur++ < max_read); 
    }); 

    read_file.close(); 
} 

Использование очевидна:

ReadFromFile(rx, Loadrx, max_numbers); 
0

Try:

void ReadFromFile(const size_t N, 
        std::vector<double> &x, 
        const std::string &file_name) 
{ 
    std::ifstream read_file(file_name); 
    assert(read_file.is_open()); 

    while (true) 
    { 
     double temp; 
     read_file >> temp; // read something 

     if(read_file.eof()) break; // exit when eof 

     x.push_back(temp);  
     if (N == x.size()) break; // exit when N elements 
    } 
    read_file.close(); 
} 

int main() 
{ 
    size_t N = 10; 
    std::vector<double> v; 
    v.reserve(N); 
    ReadFromFile(v,"Data.txt"); 
} 
Смежные вопросы