Невозможно прочитать текстовый файл с логической сеткой в ​​векторы векторов - PullRequest
1 голос
/ 04 июля 2019

У меня есть текстовый файл, который состоит из структуры типа логической сетки, как показано на рисунке.Теперь я пытаюсь прочитать текстовый файл в vector<vector<bool>> grid.Но я не могу этого сделать.Мой код завершается без каких-либо ошибок, и выполнение не перемещается внутри цикла while.

Текстовый файл имеет образец ниже:

00000000000000001111111110000
000000100000000010100000100
0000000000000000111111111000
00000000000000011111111111000
0001000000000011111111111110
00000000000000011000000011000
00000000000000100010001000100
00000000000000100000100000
00100011111111111111111001110
00000000000011111000100000001
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;

vector<vector<bool> >read_grid(const string &filename)
{
    vector<vector<bool> > gridvector;
    // Open the File
    ifstream in(filename.c_str());
    string str;
    bool tempb;// Check if object is valid
    if(!in)
    {
        cout<< "Cannot open the File : "<<filename<<endl;
        return gridvector;
    }

    // Read the next line from File untill it reaches the end.
    while (getline(in, str))
    {
        istringstream iss(str);
        vector<bool> myvector;
        while(iss>>tempb)
        {
            myvector.push_back(tempb);
        }

        gridvector.push_back(myvector);
    }

    //Close The File
    in.close();
    return gridvector;
}
 void display_grid(vector< vector<bool> >& grid) 
{
// this generates an 8 x 10 grid and sets all cells to ’0’
//vector<vector<bool> >grid(8, vector<bool>(10, 1));// printing the grid
    for(int x = 0; x < grid.size(); x++)
    {
        for(int y = 0;y < grid[x].size();y++)
        {
         // cout<<grid[x].size()<<'\n';
            cout << grid[x][y];
        }
        cout << endl;
    }
   cout<<"grid at position [1][2] is: "<< grid[1][2]<<'\n';
}
int main ()
{
    const string b_file = "intial_grid.txt";
    vector< vector<bool> > grid_copy = read_grid(b_file);
    display_grid(grid_copy);
    return 0;
}

Он завершается с состоянием выхода-1' .

Ответы [ 3 ]

3 голосов
/ 04 июля 2019

String stream возвращает true при успешном чтении и false при ошибке.

В вашем случае iss >> tempb потерпит неудачу, так как ожидает булево значение, то есть бит, но вместо этого получает строку 0 и 1.

Вы можете проверить это после первого прочтения iss >> tempb,

if (iss.fail()) {
    cout << "Failed to read\n";
}

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

// Read the next line from File untill it reaches the end.
    while (getline(in, str))
    {
        istringstream iss(str);
        vector<bool> myvector;
        char bit;
        while(iss >> bit)
        {
            myvector.push_back(bit == '1' ? true : false);
        }

        gridvector.push_back(myvector);
    }
1 голос
/ 04 июля 2019

Ответ дан и принят. Ошибки были упомянуты в комментариях.

В любом случае, я хотел бы показать «более» подход C ++, использующий алгоритмы std.

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

Это также значительно сократит количество строк кода в функции main и в целом. В определении переменной и через конструктор диапазона будут считаны все данные.

Я добавил дополнительные выходные данные для отладки, чтобы результат можно было визуализировать. Конечно, доступ к данным с помощью оператора индекса [][] также будет работать.

Пожалуйста, смотрите:


#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <sstream>

std::istringstream testData(
R"#(00000000000000001111111110000
000000100000000010100000100
0000000000000000111111111000
00000000000000011111111111000
0001000000000011111111111110
00000000000000011000000011000
00000000000000100010001000100
00000000000000100000100000
00100011111111111111111001110
00000000000011111000100000001
)#");


// We want to have a data type for one line with boolean values in a string
struct Line {
    // We overwrite the extractor operator >> . With that we can easily read a complete line
    friend std::istream& operator >> (std::istream& is, Line& l) { 
        std::string line{}; l.lineOfBool.clear(); getline(is, line);
        std::transform(line.begin(), line.end(), std::back_inserter(l.lineOfBool), [](const char c) { return (c == '1') ? true : false; });
        return is; }

    // Type cast operator to expected value
    operator std::vector<bool>() const { return lineOfBool; }
    // The data
    std::vector<bool> lineOfBool{};
};

int main()
{
    // Define the variable that will hold all bool data of the complete file. The range constructor will read the file 
    std::vector<std::vector<bool>> fileAsStrings{std::istream_iterator<Line>(testData),std::istream_iterator<Line>() };

    // For debug purposes: Copy all Data to std::cout
    std::for_each(fileAsStrings.begin(), fileAsStrings.end(), [](const std::vector<bool> & l) {std::copy(l.begin(), l.end(), std::ostream_iterator<bool>(std::cout, " ")); std::cout << '\n'; });

    return 0;
}

Обратите внимание: я читаю из потока istringstream, инициализированного необработанной строкой. Таким образом, нет разницы для чтения из файла.

Может быть, кто-то найдет это решение полезным.

0 голосов
/ 04 июля 2019

Ошибка 'состояние выхода -1' вызвана функцией display_grid () , компоненты являются векторными, а доступ к вектору равен verctorVariable.at();

другая ошибка - while(iss>>tempb), потому что ваш результат - весь ряд, вы решаете эту проблему с помощью этого кода

istringstream iss(str);
vector<bool> myvector;
string value;
iss >> value;
cout << value;
for(char c : value){
   cout << "**** debug print: " << c << endl;
   myvector.push_back((bool)(c-'0'));
}
gridvector.push_back(myvector);

также, ваш метод display_grid () должен быть таким

void display_grid(vector< vector<bool> >& grid)
{
// this generates an 8 x 10 grid and sets all cells to ’0’
//vector<vector<bool> >grid(8, vector<bool>(10, 1));// printing the grid

    for(int x = 0; x < grid.size(); x++)
    {
        cout<<"addin another elemen";
        for(int y = 0;y < grid[x].size();y++)
        {
             cout<<"addin another elemen";

            cout << grid.at(x).at(y);
        }
        cout << endl;
    }

    //cout<<"grid at position [1][2] is: "<< grid[1][2]<<'\n';
}

Этот код возвращает этот код выхода Процесс завершен с кодом выхода 0

...