Question bête, on ne sait pas à qui on a affaire !!
Tu es quoi : étudiant ? jeune bidouilleur en herbe (qui apprend en fouillant sur le web) ? ...
Tout ça pour éviter de te perdre avec une réponse super technique que tu comprendrais mal.
Question bête, on ne sait pas à qui on a affaire !!
Tu es quoi : étudiant ? jeune bidouilleur en herbe (qui apprend en fouillant sur le web) ? ...
Tout ça pour éviter de te perdre avec une réponse super technique que tu comprendrais mal.
Bonjour,
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> main() { int i=0; int j=0; int k=0; //int l=1; char c=0; char**a; //char *s[20]; //a[65][25]=new (char); for(j=1;j<=25;j++){ a[i][j]=(char)malloc(65*25*sizeof(char)); } for(i=1;i<=65;i++){ a[i]=(char*)malloc(sizeof*a[i]*25); } i=1; j=1; FILE *fp=fopen("/sdcard/GDE.Main/tt.txt","r"); //FILE *f=tmpfile(); for(i=1;i<=1625;i++){ char c; c=fgetc(fp); printf("%c",c); if (isprint(c)==0 && isspace(c)!=0) { j++; k=1; //l=0; } //if (toascii(c)==atoi("013"))j++; if (isprint(c)!=0 && isspace(c)!=0){ k++; //l=0; } if(feof(fp)!=0)break; //a[j][k]=(char*)calloc(10,sizeof(char)); //if (l=0){ //a[j][k]=(char*)realloc(10,sizeof(char)); //a[j][k]=new char; //l=1; //} //s[j]=(char*)malloc(20); //(const char*)c=(const char*)malloc(1); //strcat(a[j][k],(const char*)c); //strcat(a[j][k],c); //sscanf(a[j][k],"%10s",s[1]); if (isspace(c)==0){ sprintf(a[j][k],"%s%c",a[j][k],c); } }; //printf("%c",s[1]); printf("%s",a[3][2]); printf("(%d",j); printf("/%d)",k); //fclose(f); fclose(fp); return 0; }
Je suis toujours bloqué J'ai laissé toutes mes pistes en commentaires sinon je me rends compte qu'à force de modifications ça ne ressemble plus à rien et on ne sait plus d'où vient telle ou telle variable déclarée non utilisée et des morceaux de codes ineptes se trouvent postés aussi.
Pour cibler dans ce fouillis:si je mets l'allocation dans la boucle principale:j'écrase le début de ma chaine;j'alloue en dehors comme ici je me retrouve avec un char* (???) dans sprintf qui n'est pas accepté.
Je ne peux pas conditionner l'allocation dans la boucle principale non plus.
En effet, on ne voit plus trop ce que le programme est censé faire...
Un petit détail : indenter le code permet une meilleure lisibilité, en particulier pour ceux qui ne l'ont pas écrit.
Autre chose :Tu alloues la dimension 2 avant la dimension1.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 char**a; for (j = 1; j <= 25; j++) { a[i][j] = (char) malloc(65 * 25 * sizeof(char)); } for (i = 1; i <= 65; i++) { a[i] = (char*) malloc(sizeof * a[i] * 25); }
Tu penses vraiment que ça peut fonctionner ?
En supposant que la première partie ne fasse pas planter violemment le programme, dans la deuxième partie tu perds les adresses que tu viens de récupérer.
De toutes façons, tes allocations sont fausses...
Pour allouer un tableau dynamique à deux dimensions, de NB_LIGNES lignes et NB_COLONNES et de type T, on le fait comme ceci :Bon, d'après ce que j'ai compris, je peux te proposer une solution.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 T **tab; // Allocation des lignes tab = (T **) malloc(NB_LIGNES * sizeof(T *)); // Allocation des cellules for (i = 0; i < NB_LIGNES; ++i) tab[i] = (T *) malloc(NB_COLONNES * sizeof(T)); // À présent, on peut accéder à tab[i][j]. (...) // Ne pas oublier de libérer les ressources lorsque l'on n'en a plus besoin !!! for (i = 0; i < NB_LIGNES; ++i) free(tab[i]); // L'accès à tab[i][j] est illégal !!! free(tab); tab = NULL; // Facultatif, juste pour être sûr que personne n'accédera à la valeur caduque de tab.
Je pars du principe que le nom du fichier est stocké dans la variable char const *fichier.
De plus, je suppose que le tableau char ***mots a été correctement alloué (statiquement ou dynamiquement) sur les deux premières dimensions, et qu'il est suffisamment grand pour contenir chaque mot de chaque ligne.
Il est important de vérifier qu'un flux a bien été ouvert avant de tenter de l'utiliser.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 FILE *fp = fopen(fichier, "r"); if (fp == NULL) { fprintf(stderr, "Impossible d'ouvrir le fichier %s.\n", fichier); exit(EXIT_FAILURE); }
Sinon, attends-toi à une belle erreur de segmentation lorsque tu voudras lire ou écrire des données...
Je prends le parti de n'allouer les chaînes du tableau à la bonne taille.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 // Variables d'accès aux éléments du tableau int ligne = 0; int colonne = 0; // Chaîne de caractères temporaire pour stocker les mots en cours de lecture // Taille maximale à adapter aux besoins char tmp[MAX_LONG]; int index = 0; // Position dans la chaîne temporaire // Variable stockant le dernier caractère lu int c; // Lecture du fichier... c = fgetc(fp); while (c != EOF) { // fgetc retourne EOF lorsque la fin du fichier est atteinte if (c == '\n') { // On est à la fin d'une ligne ++ligne; colonne = 0; } else if (isspace(c)) { // On a lu un caractère d'espacement, donc on est à la fin d'un mot tmp[index] = '\0'; // Le caractère NUL indique la fin de chaîne mots[ligne][colonne] = (char *) malloc((index + 1) * sizeof(char)); // Allocation de la mémoire nécessaire dans le tableau => ne pas oublier de désallouer en fin de programme ! strcpy(mots[ligne][colonne], tmp); ++colonne; index = 0; } else { // On a lu un caractère normal, on le place à la fin de la chaîne temporaire tmp[index] = c; ++index; } c = fgetc(fp); }
Mais cela nécessite de la connaître au préalable.
C'est pourquoi j'ai besoin d'une chaîne de caractères annexe pour stocker temporairement les mots lu ; on suppose qu'elle est suffisamment grande pour contenir chacun d'entre eux.
Une fois un mot lu, on peut déterminer sa longueur, et ainsi allouer l'espace juste nécessaire pour le stocker.
Il ne reste plus qu'à le copier dans le tableau.
Lors de la libération des ressources, il faudra faire attention aux chaînes qui n'ont finalement pas été allouées.
Une autre possibilité est de déterminer à l'avance une longueur qu'aucun mot ne dépassera, et allouer chaque chaîne du tableau avec cette longueur.
On évite ainsi de passer par une chaîne auxilliaire, mais on va réserver de la place pour rien.
Concernant la boucle while de lecture, on peut la transformer en une boucle do while équivalente :D'un côté on écrit l'expression de mise à jour 2 fois, de l'autre c'est le test de fin de boucle.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 do { c = fgetc(fp); if (c != EOF) { // Traitements durant la lecture... } } while (c != EOF);
Comme tout bout de code dupliqué, c'est sujet à erreur, lors de modifications notemment.
Aucune boucle n'est a priori plus sûre que l'autre.
Voilà.
À la fin de l'algo, tu obtiens dans mots[i][j] le (i+1)-ième mot de la (j+1)-ième colonne (s'il existe).
En espérant que ça corresponde à ce que tu souhaitais...
Ceci dit, il y a tout de même quelques restrictions.
En plus des hypothèses posées au début, je suppose que le fichier suit la convention UNIX pour les fins de ligne, et qu'il n'y peut pas y avoir plusieurs caractères d'espacement à la suite.
Partager