Lire le tableau de nombres dans des tableaux lorsque le nombre de lignes et de colonnes déterminé lors de l’exécution

J’aimerais vous poser des questions sur la saisie de données. J’ai un fichier texte au format suivant:

7 2

XY

dix
2 0,048922
3 0,0978829
4 0.146908
5 0,196019
6 0.245239
7 0,294584

La première ligne contient le nombre de lignes et de colonnes à lire. La deuxième ligne contient des en-têtes. À partir de la troisième ligne, ce ne sont que des données. Je voudrais lire mes données dans un tableau 2D (mat [] []) et les en-têtes dans un tableau de chaînes (title []), qui pourraient être facilement référencées ultérieurement Je suis venu jusqu’ici en écrivant le script. Il peut lire les numéros de tableau dans le tableau, mais pas les chiffres 2D. J’essayais de déclarer un pointeur pour la masortingce qui est passé à la fonction mais je ne pouvais pas le faire. J’ai aussi essayé getline () mais je ne sais pas comment séparer les en-têtes \ t délimités en chaînes séparées.

#include  #include  #include  #include  using namespace std; void readFile(char[]); int main(){ char fileName[] = "results.txt"; readFile(fileName); return 0; } // Read file to masortingx void readFile(char fileName[]){ int m, n; // Create streamobject ifstream infile; infile.open(fileName); // Exit if file opening failed if (!infile.is_open()){ cerr<<"Opening failed"<> m >> n; // Pre-allocate memory ssortingng title; float *mat=new float[m*n]; // Read title // Start reading data while (!infile.eof()){ for(int i=0; i<m; i++){ for(int j=0; j> mat[i*n+j]; } } } infile.close(); } 

Quelqu’un pourrait m’aider?


Merci pour l’aide jusqu’ici. Je vais me pencher sur l’application de vecteurs ce week-end, mais je dois en prendre connaissance. J’ai rapidement changé de script pour qu’il fasse maintenant ce que je voulais: renvoie un pointeur sur un tableau “mat” avec les valeurs. J’ai une fonction appelée ‘showMasortingx’, qui l’affiche à l’écran. Si j’appelle showMasortingx dans la fonction ‘readFile’, cela fonctionne bien. Par contre, si je l’appelle en dehors du script principal, les valeurs renvoyées sont totalement fausses.

J’ai l’impression qu’il y a quelque chose qui ne va pas ici. Pourriez-vous s’il vous plaît aider à le souligner?

 #include  #include  #include  #include  using namespace std; void readFile(char[],float *mat,int &m,int &n); void showMasortingx(float *mat,int m,int n); /******************************************************************* Script *******************************************************************/ int main(){ char fileName[] = "results.txt"; int m, n; float *mat; // Read data from file readFile(fileName,mat,m,n); showMasortingx(mat,m,n); return 0; } // Read file to masortingx void readFile(char fileName[],float *mat,int &m,int &n){ // Create streamobject ifstream infile; infile.open(fileName); // Exit if file opening failed if (!infile.is_open()){ cerr<<"Opening failed"<> m >> n; // Pre-allocate memory mat=new float[m*n]; // Read title std::ssortingng X; std::ssortingng Y; infile >> X >> Y; // Reading data while (!infile.eof()){ for(int i=0; i<m; i++){ for(int j=0; j> mat[i*n+j]; } } } // showMasortingx(mat,m,n); infile.close(); } // Print masortingx to screen void showMasortingx(float *x,int m, int n){ for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ cout << x[i*n+j] << "\t"; } cout << endl; } } 

Notez faire ceci:

 while (!infile.eof()){ 

Est presque toujours faux. Si la lecture du fichier échoue pour une raison autre que eof, vous entrez une boucle infinie.

De plus, la manière dont le code est organisé signifie que vous essayez d’initialiser vos données deux fois (même si cela échouera lors de la deuxième passe et que rien ne sera fait (à part refaire la boucle)) car le drapeau eof n’est pas défini tant que vous lisez au-delà de l’EOF et puisque vous savez que la quantité de données à lire pour votre premier passage ne lira pas au-delà de l’EOF, vous lirez jusqu’à la fin (mais pas après).

Lecture dans un tableau 1D

 int main() { std::ifstream file("plop"); int n; int m; std::ssortingng ColHeadX; std::ssortingng ColHeadY; // You forgot to read the Col Header out. // Just read them into ssortingngs. file >> n >> m >> ColHeadX >> ColHeadY; // Don't do manual memory management. // Use a vector it will do the work for you. std::vector data(n*m); // initialized with (n*m) elemensts // Always put the read in the loop test // This bit: file >> data[loop] // If this read fails you want the loop to exit immediately. // By putting the read here the result of the read will be // tested to see if it worked. for(int loop=0;loop < (n*m) && (file >> data[loop]); ++loop) { /*Empty*/} } 

La lecture dans un tableau 2D est presque aussi simple:

 int main() { std::ifstream file("plop"); int n; int m; std::ssortingng ColHeadX; std::ssortingng ColHeadY; // You forgot to read the Col Header out. // Just read them into ssortingngs. file >> n >> m >> ColHeadX >> ColHeadY; // Don't do manual memory management. // A vector of vectors gives you a 2D array. // The initialize(r) is slightly more complex but given the example above // I think you should be able to see the outer vector is initialized with // n copies of a vector with m elements. std::vector > data(n,std::vector(m)); // Again I would advise putting the read in the loop condition // The easiest way here is then to calculate the x/y coordinates in the body as you go. for(int loop=0, x=0, y=0;loop < (n*m) && (file >> data[x][y]);) { ++loop x = loop % n; y = loop / n; } } 

Pour allouer le tableau à deux dimensions dans votre fonction, utilisez:

 float **mat = new float*[m]; for(int i=0; i 

Ensuite, vous pouvez changer infile >> mat[i*n+j]; à:

 infile >> mat[i][j]; 

Enfin, assurez-vous d’implémenter la lecture du titre; en ce moment c'est vide:

 //Read title 

En C et C ++, les pointeurs (C et C ++) et les références (C ++ uniquement) aux tableaux sont déclarés avec une syntaxe quelque peu obscure, comme ceci:

 void fp(float (*array)[10]); void fr(float (&array)[10]); void f2d(float (&array)[10][10]); void main() { float a[10]; fp(&a); fr(a); float b[10][10]; f2d(b); } 

Vous ne pouvez pas déclarer un pointeur ou une référence à un tableau qui n’a pas une taille constante au moment de la compilation. Pour transmettre des données de taille variable, vous devez utiliser un pointeur sur le premier élément du tableau et indiquer la taille des données, afin que votre code puisse utiliser le tableau en toute sécurité, sans limite de limite, comme ceci:

 void f(float* data, int length); 

Cependant, cela oblige le programmeur à écrire avec soin un code correct et sûr. Puisque vous utilisez C ++ et non C, utiliser std::vector est fortement recommandé! vector est un object conteneur séquentiel qui se comporte comme un tableau lorsque vous devez y indexer. Il est redimensionnable dynamicment et traitera pour vous les détails de l’allocation et de la désallocation.

Comme indiqué ci-dessus, vous ne pouvez pas allouer de manière dynamic un tableau multidimensionnel car toutes les dimensions sauf une doivent être connues au moment de la compilation. Bien que vous puissiez utiliser std::vector > , il est préférable de créer un type Masortingx. Voici un exemple (très simplifié):

 class Masortingx { public: Masortingx (int _m, int _n) : m(_m), n(_n), t(m * n) {} float& operator() (int i, int j) { return t[i * n + j]; } int size_x () { return m; } int size_y () { return n; } private: int m; int n; std::vector t; }; std::ostream &operator<<(std::ostream &os, Matrix mat) { for (int i = 0; i < mat.size_x(); i++) { for (int j = 0; j < mat.size_y(); j++) { os << mat(i,j) << ' '; } os << '\n'; } return os; } 

Bien sûr, vous devriez utiliser une bibliothèque existante telle que uBLAS .