J'ai un fichier texte qui se compose d'une grille booléenne comme la structure comme indiqué. Maintenant, j'essaye de lire le fichier texte dans une grille vector
. Mais je suis incapable de le faire. Mon code se termine sans aucune erreur et l'exécution ne se déplace pas dans la boucle while
.
Le fichier texte contient l'exemple ci-dessous:
#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; }
00000000000000001111111110000 000000100000000010100000100 0000000000000000111111111000 00000000000000011111111111000 0001000000000011111111111110 00000000000000011000000011000 00000000000000100010001000100 00000000000000100000100000 00100011111111111111111001110 00000000000011111000100000001
3 Réponses :
L'erreur 'exit status -1' est causée à la fonction display_grid () , les composants sont vectoriels et l'accès au vecteur est verctorVariable.at ();
une autre erreur est while (iss >> tempb)
parce que votre résultat est toute ligne, vous résolvez ce problème avec ce code
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'; }
mais où est-ce que je pousse les valeurs booléennes dans myvector dans le code ci-dessus?
Merci pour grid_display mais le code d'entrée, je ne pense pas que cela fonctionnera pour stocker les valeurs booléennes dans le vecteur
Je ne pense pas que le at
dans grid.at (x) .at (y)
soit utile ici. Les boucles for
garantissent que x
et y
sont dans les limites.
Si vous allez lire des caractères individuels à partir d'une ligne, il n'y a aucun intérêt à utiliser istringstream
. Vous pouvez parcourir la ligne directement: for (char c: str)
Le flux de chaînes renvoie vrai en cas de lecture réussie et faux en cas d'erreur.
Dans votre cas, iss >> tempb
échouera car il attend une valeur booléenne, c'est-à-dire un peu, mais reçoit à la place une chaîne de 0 et 1.
Vous pouvez vérifier cela après la première lecture de iss >> tempb
,
// 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); }
Vous pouvez à la place parcourir les caractères individuellement.
if (iss.fail()) { cout << "Failed to read\n"; }
Cela fonctionne beaucoup, je suis capable d'obtenir un vecteur de vecteur avec un fichier lu.
La réponse est donnée et acceptée. Les erreurs ont été mentionnées dans les commentaires.
Quoi qu'il en soit, je voudrais montrer une approche "plus" C ++, en utilisant des algorithmes std.
L'idée est que nous voulons lire une ligne avec des valeurs booléennes . J'ai donc conçu un nouveau type de données, une classe, qui contient de telles données et sait également comment les lire. À mon humble avis, les données et les méthodes devraient être regroupées dans une classe.
Cela réduira également considérablement les lignes de code dans la fonction main et globalement. Dans la définition de la variable et via le constructeur de plage, toutes les données seront lues.
J'ai ajouté une sortie de débogage supplémentaire, afin que le résultat puisse être visualisé. Bien sûr, l'accès aux données à l'aide de l'opérateur d'index [] []
fonctionnera également.
Veuillez consulter:
#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; }
Remarque: je lis depuis un istringstream, initialisé avec une chaîne brute. Donc, aucune différence avec la lecture d'un fichier.
Peut-être que quelqu'un trouvera cette solution utile.
Pourquoi pas std :: transform (line.begin (), line.end (), l.lineOfBool.begin (), [] (const char c) {return (c == '1')? True: false;});
de cette façon, il n'est pas nécessaire d'appeler l.lineOfBool.clear ()
sur chaque ligne.
@CaptainDaVinci. Correct. Merci! Encore mieux! +1
Où les choses commencent-elles exactement à mal tourner? Que se passe-t-il si vous n'utilisez pas une fonction distincte (pensez à exemple reproductible minimal )? Veuillez également formater / indenter votre code de manière cohérente, de préférence en utilisant un formateur automatique. En tant que nouvel utilisateur, suivez également la visite et lisez Comment demander .
Je ne sais pas où cela va mal mais je vois que le contrôle ne va pas à l'intérieur pendant que (iss << tempb) du tout
Vérifiez std :: bitset
Une question, se pourrait-il que les bits avec 0 soient ignorés pour l'optimisation? et devons-nous préciser que nous voulons les inclure? J'ai eu un problème similaire et je l'ai résolu de cette façon
Non @vincenzopalazzo, j'ai besoin de lire toutes les lignes et colonnes de zéros et de uns dans une grille de vecteur
" Il sort avec 'état de sortie -1'. " - cela signifie que votre code plante avant d'atteindre la fin de
main ()
. Exécutez le code dans un débogueur et découvrez ce qui se passe réellementJ'utilise un compilateur en ligne mais je vais faire le débogage @RemyLebeau
pouvez-vous poster la méthode display_grid (), s'il vous plaît?
Je viens de faire @vincenzopalazzo
Remarque
vector
est tellement différent d'unvecteur
qu'il obtient sa propre page de documentation . Beaucoup de pièges là-dedans.Dans votre cas,
iss >> tempb
échouera car il attend une valeur booléenne, c'est-à-dire un peu, mais reçoit à la place une chaîne de 0 et 1.merci @CaptainDaVinci toute solution à ce problème sera très utile