[C] Problème avec sscanf
Résolu/Fermé
Bakux
Messages postés
1195
Date d'inscription
jeudi 19 février 2009
Statut
Membre
Dernière intervention
5 juillet 2015
-
2 juin 2012 à 19:55
Bakux Messages postés 1195 Date d'inscription jeudi 19 février 2009 Statut Membre Dernière intervention 5 juillet 2015 - 3 juin 2012 à 18:10
Bakux Messages postés 1195 Date d'inscription jeudi 19 février 2009 Statut Membre Dernière intervention 5 juillet 2015 - 3 juin 2012 à 18:10
9 réponses
Utilisateur anonyme
2 juin 2012 à 22:08
2 juin 2012 à 22:08
char chaine[] = "";
Grosse erreur... Ceci ne réserve qu'un octet pour ta chaine, (le 0 final).
Chaque fois que tu fais fgets et que tu écris dans 'chaine', ça déborde sur d'autres variables... Ça explique bien des choses.
Puisque tu autorises ton fgets à lire jusqu'à 200 caractères, il faut en réserver au moins 200 :
char chaine[201] = ""; (je compte 1 de plus parce que je ne sais jamais si le 0 final est compté ou pas dans les 200 du fgets.
De plus, pour scanner des ix et iy qui sont des long, il me semble qu'il faut utiliser %ld et non pas simplement %d.
Grosse erreur... Ceci ne réserve qu'un octet pour ta chaine, (le 0 final).
Chaque fois que tu fais fgets et que tu écris dans 'chaine', ça déborde sur d'autres variables... Ça explique bien des choses.
Puisque tu autorises ton fgets à lire jusqu'à 200 caractères, il faut en réserver au moins 200 :
char chaine[201] = ""; (je compte 1 de plus parce que je ne sais jamais si le 0 final est compté ou pas dans les 200 du fgets.
De plus, pour scanner des ix et iy qui sont des long, il me semble qu'il faut utiliser %ld et non pas simplement %d.
Utilisateur anonyme
Modifié par le père. le 2/06/2012 à 21:36
Modifié par le père. le 2/06/2012 à 21:36
Bonjour
C'est marrant, le codage en mémoire de 741354544 est le même que ',0,0' et celui de 741354545 le même que ',0,1' - en big endian.
Tu as bien vérifié le contenu de ton fichier de départ ?
Comment sont déclarées tes variables ix,iy,iz et chaine ?
C'est marrant, le codage en mémoire de 741354544 est le même que ',0,0' et celui de 741354545 le même que ',0,1' - en big endian.
Tu as bien vérifié le contenu de ton fichier de départ ?
Comment sont déclarées tes variables ix,iy,iz et chaine ?
Bakux
Messages postés
1195
Date d'inscription
jeudi 19 février 2009
Statut
Membre
Dernière intervention
5 juillet 2015
187
2 juin 2012 à 21:40
2 juin 2012 à 21:40
Le fichier est OK, et je déclare les variables comme ceci :
long ix = 0, iy = 0; int iz = 0; char chaine[] = "";
Bakux
Messages postés
1195
Date d'inscription
jeudi 19 février 2009
Statut
Membre
Dernière intervention
5 juillet 2015
187
2 juin 2012 à 22:25
2 juin 2012 à 22:25
En effet, le problème venait du chaîne, mais maintenant le programme se referme immédiatement dès son ouverture :
Process returned 3 <0x3>
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 835
Modifié par fiddy le 2/06/2012 à 22:26
Modifié par fiddy le 2/06/2012 à 22:26
Faudrait que tu repostes ton code en tenant compte de nos remarque car là on est un peu aveugle.
As-tu bien mis un "system("pause");" (si t'es sous windows) avant ton return 0; final ?
As-tu bien mis un "system("pause");" (si t'es sous windows) avant ton return 0; final ?
Bakux
Messages postés
1195
Date d'inscription
jeudi 19 février 2009
Statut
Membre
Dernière intervention
5 juillet 2015
187
2 juin 2012 à 22:30
2 juin 2012 à 22:30
#include <stdlib.h> #include <stdio.h> #include <iostream> #include <string> #include <SDL.h> #include <SDL_image.h> /* Inclusion du header de SDL_image (adapter le dossier au besoin) */ #define TAILLE_BLOC 34 // Taille d'un bloc (carré) en pixels #define NB_BLOCS_LARGEUR 12 #define NB_BLOCS_HAUTEUR 12 #define LARGEUR_FENETRE TAILLE_BLOC * NB_BLOCS_LARGEUR #define HAUTEUR_FENETRE TAILLE_BLOC * NB_BLOCS_HAUTEUR int main(int argc, char *argv[]) { SDL_Surface *screen = NULL, *mario = NULL, *back = NULL, *surf = NULL, *objet = NULL; SDL_Rect positionMario, positionBloc; SDL_Event event; int quit = 1; int o = 0; long ix = 0, iy = 0; int iz = 0; char chaine[21] = ""; char bloc[1000][1000]; SDL_Init(SDL_INIT_VIDEO); positionMario.x = 34; positionMario.y = 34; screen = SDL_SetVideoMode(LARGEUR_FENETRE, HAUTEUR_FENETRE, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); SDL_WM_SetCaption("Mario Sokoban", NULL); SDL_EnableKeyRepeat(100,100); SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255)); mario = IMG_Load("mario_bas.gif"); FILE* fichier = NULL; fichier = fopen("niveau2.lvl", "r"); while (fgets(chaine, 20, fichier) != NULL) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL) { sscanf(chaine, "%ld, %ld, %d",&ix, &iy, &iz); //printf("ix : %d iy : %d iz : %d \n",ix, iy, iz); ix *= TAILLE_BLOC; iy *= TAILLE_BLOC; //printf("ix : %d, iy : %d, iz : %d \n",ix, iy, iz); if(iz>=0 && iz<=3){ switch(iz){ case 0: surf = IMG_Load("sol.jpg"); bloc[ix][iy]= 0; break; case 1: surf = IMG_Load("mur.jpg"); bloc[ix][iy]= 1; break; case 2: surf = IMG_Load("caisse.jpg"); bloc[ix][iy]= 2; break; case 3: o = 1; surf = IMG_Load("sol.jpg"); bloc[ix][iy]= 3; break; } }else{ // perror("iz : %d", iz); } positionBloc.x = ix; positionBloc.y = iy; SDL_BlitSurface(surf, NULL, screen, &positionBloc); if(o){ objet = IMG_Load("objectif.png"); SDL_SetColorKey(objet, SDL_SRCCOLORKEY, SDL_MapRGB(screen->format, 255,255,255)); SDL_BlitSurface(objet, NULL, screen, &positionBloc); } SDL_Flip(screen); o = 0; } fclose(fichier); while(quit){ SDL_WaitEvent(&event); switch(event.type){ case SDL_QUIT: quit = 0; break; case SDL_KEYDOWN: back = IMG_Load("sol.jpg"); SDL_BlitSurface(back, NULL, screen, &positionMario); SDL_Flip(screen); switch(event.key.keysym.sym){ case SDLK_DOWN: if(positionMario.y < (HAUTEUR_FENETRE - TAILLE_BLOC) && bloc[positionMario.x][positionMario.y+TAILLE_BLOC] != 1){ positionMario.y += TAILLE_BLOC; mario = IMG_Load("mario_bas.gif"); } break; case SDLK_UP: if(positionMario.y >= TAILLE_BLOC && bloc[positionMario.x][positionMario.y-TAILLE_BLOC] != 1){ positionMario.y -= TAILLE_BLOC; mario = IMG_Load("mario_haut.gif"); } break; case SDLK_LEFT: if(positionMario.x >= (TAILLE_BLOC) && bloc[positionMario.x-TAILLE_BLOC][positionMario.y] != 1){ positionMario.x -= TAILLE_BLOC; mario = IMG_Load("mario_gauche.gif"); } break; case SDLK_RIGHT: if(positionMario.x < (LARGEUR_FENETRE - TAILLE_BLOC) && bloc[positionMario.x+TAILLE_BLOC][positionMario.y] != 1){ positionMario.x += TAILLE_BLOC; mario = IMG_Load("mario_droite.gif"); } break; case SDLK_ESCAPE: quit = 0; break; } break; } printf("Etat Mario : %d \n", bloc[positionMario.x][positionMario.y]); //SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255)); SDL_BlitSurface(mario, NULL, screen, &positionMario); SDL_Flip(screen); } SDL_Quit(); return 0; }
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Utilisateur anonyme
Modifié par le père. le 2/06/2012 à 22:30
Modifié par le père. le 2/06/2012 à 22:30
Dans le bout de programme que tu nous as montré, il n'y a rien pour le faire attendre. Il a fini son travail, il s'arrête, où est le problème ?
Quant au Process returned 3 , c'est sans doute que tu n'as mis aucune instruction return à la fin de ton main. Ajoute un return 0; avant de quitter le main.
Quant au Process returned 3 , c'est sans doute que tu n'as mis aucune instruction return à la fin de ton main. Ajoute un return 0; avant de quitter le main.
Utilisateur anonyme
2 juin 2012 à 22:34
2 juin 2012 à 22:34
Personnellement, je jette l'éponge. Il s'agit probablement d'un problème d'utilisation de la bibliothèque SDL, que je ne connais pas du tout. Bonne chance
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 835
2 juin 2012 à 23:19
2 juin 2012 à 23:19
Pourquoi mélanger les entêtes C++ et de C ?
Au final c'est du C ou du C++ que tu souhaites faire ?
sscanf(chaine, "%ld, %ld, %d",&ix, &iy, &iz);
Ok pour le sscanf, mais il faut faire pareil pour le printf.
Tu n'as pas tenu compte de ma remarque : system("pause"); avant le return 0; final (si t'es sous windows) sinon indique nous ton OS.
Au final c'est du C ou du C++ que tu souhaites faire ?
sscanf(chaine, "%ld, %ld, %d",&ix, &iy, &iz);
Ok pour le sscanf, mais il faut faire pareil pour le printf.
Tu n'as pas tenu compte de ma remarque : system("pause"); avant le return 0; final (si t'es sous windows) sinon indique nous ton OS.
Bakux
Messages postés
1195
Date d'inscription
jeudi 19 février 2009
Statut
Membre
Dernière intervention
5 juillet 2015
187
2 juin 2012 à 23:28
2 juin 2012 à 23:28
Le system("pause"); ne sert à rien, j'ai une boucle infini avec quit, qui sort de la boucle dès l'appui sur Echap.
Ensuite le printf est en commentaire, donc useless aussi, et les entêtes sont bien en C, ce que je souhaite faire.
OS : Windows
Ensuite le printf est en commentaire, donc useless aussi, et les entêtes sont bien en C, ce que je souhaite faire.
OS : Windows
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 835
2 juin 2012 à 23:52
2 juin 2012 à 23:52
Le system("pause"); ne sert à rien, j'ai une boucle infini avec quit, qui sort de la boucle dès l'appui sur Echap.
Beh justement, là la fenêtre ne se refermera pas après avoir appuyé sur Echap...
Ou alors, précise ce que tu souhaites faire en détail. Car à part "ça boucle en infini et la fenêtre se referme en appuyant sur Echap", on ne sait pas grand chose d'autre.
Ensuite le printf est en commentaire, donc useless aussi,
Certes. Je te disais ça car c'est mieux qu'un commentaire soit juste. Le jour où tu enlèveras le commentaire, ça sera bon. En plus ça coûte rien de rajouter un %ld. Enfin c'est toi qui vois.
et les entêtes sont bien en C, ce que je souhaite faire.
Non...
iostream c'est C++, string c'est C++ (à ne pas confondre avec string.h). Le mélange d'entête est à proscrire. C'est loin d'être useless.
En plus ton code est dur à comprendre. Il n'y a pas de fonctions. Les fonctions sont justement là pour faciliter la lecture d'un code.
Beh justement, là la fenêtre ne se refermera pas après avoir appuyé sur Echap...
Ou alors, précise ce que tu souhaites faire en détail. Car à part "ça boucle en infini et la fenêtre se referme en appuyant sur Echap", on ne sait pas grand chose d'autre.
Ensuite le printf est en commentaire, donc useless aussi,
Certes. Je te disais ça car c'est mieux qu'un commentaire soit juste. Le jour où tu enlèveras le commentaire, ça sera bon. En plus ça coûte rien de rajouter un %ld. Enfin c'est toi qui vois.
et les entêtes sont bien en C, ce que je souhaite faire.
Non...
iostream c'est C++, string c'est C++ (à ne pas confondre avec string.h). Le mélange d'entête est à proscrire. C'est loin d'être useless.
En plus ton code est dur à comprendre. Il n'y a pas de fonctions. Les fonctions sont justement là pour faciliter la lecture d'un code.
Bakux
Messages postés
1195
Date d'inscription
jeudi 19 février 2009
Statut
Membre
Dernière intervention
5 juillet 2015
187
3 juin 2012 à 08:37
3 juin 2012 à 08:37
Le problème venait d'un array qui n'était pas assez grand, et merci pour les conseils ;)
fiddy
Messages postés
11069
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
23 avril 2022
1 835
3 juin 2012 à 18:05
3 juin 2012 à 18:05
Ok. Il n'empêche que tu as également des problèmes là où je t'ai signalé ;-)))).
Bakux
Messages postés
1195
Date d'inscription
jeudi 19 février 2009
Statut
Membre
Dernière intervention
5 juillet 2015
187
3 juin 2012 à 18:10
3 juin 2012 à 18:10
Ouaip, j'ai tout mis en plusieurs fonctions, rétablis le %ld au lieu des %d, vérifier les entêtes ;)
2 juin 2012 à 22:17
Oui il est compté dedans. fgets lira 199 caractères et mettre en 200ème position le '\0' (si les caractères EOF ou '\n' n'ont pas été lus avant bien sûr).
De plus, pour scanner des ix et iy qui sont des long, il me semble qu'il faut utiliser %ld et non pas simplement %d.
Je confirme.
2 juin 2012 à 22:23