Précédent   Forum des professionnels en informatique > C et C++ > C
C Forum d'entraide technique sur le langage C. Avant de poster -> F.A.Q. C, Avant de poster.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/01/2007, 14h03   #1
Membre du Club
 
Inscription : juin 2005
Messages : 220
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 220
Points : 47
Points : 47
Par défaut Léger soucis de fscanf

Salut tout le monde !

Voilà, je dispose d'un fichier contenant des commandes, par exemple :
Code :
1
2
3
ls
ls -a -i /dev/
who
J'aimerai pouvoir stocker dans un tableau à 2 dimensions sont contenus, ce qui donnerai :

Code :
1
2
3
4
 
Tab[0][0] = "ls"
Tab[1][0] = "ls" Tab[1][1] = "-a" Tab[1][2] = "-i" Tab[1][3] = "/dev"
Tab[2][0] = "who"
Pour cela j'ai commencé à codé cela :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
 
typedef struct
{
	char nomCommande[COMMAND_LIMIT];
	char option[50];
	char parametre[PARAMETER_LIMIT];
} Commande;
.............................
 
Commande *cmd;
.............................
	while (feof(fichier) == 0)
	{
		fscanf(fichier, "%s%s%s", cmd[i].nomCommande, cmd[i].option, cmd[i].parametre);
		printf ("%s%s%s\n",cmd[i].nomCommande, cmd[i].option, cmd[i].parametre);
 
		i++;
	}
Est-il possible de tester ce que l'on récupère du fscanf ? Car si on tombe sur un "ls" sans option et sans paramètre alors il prendra pour le cmd[i].option le cmd[i+1].nomCommande...

D'avance un très grand merci et bonne semaine !!
soad029 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2007, 17h45   #2
Membre du Club
 
Inscription : septembre 2005
Messages : 151
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

Informations forums :
Inscription : septembre 2005
Messages : 151
Points : 48
Points : 48
Envoyer un message via MSN à Nico_stras
commence par utiliser la fonction "fgets" pour isoler une ligne



Code :
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
#include "stdafx.h"
 
#define COMMAND_LIMIT  20
#define PARAMETER_LIMIT  20
	typedef struct
{
	char nomCommande[COMMAND_LIMIT];
	char option[50];
	char parametre[PARAMETER_LIMIT];
} Commande;
 
	int _tmain(int argc, _TCHAR* argv[])
{
	Commande cmd [20]; // Pas de pointeur, il faut alouer la mémoire pour la structure
	FILE* fichier=fopen("c:\\fichier.txt","r");
    int i=0 ;
	while (feof(fichier) == 0)
	{
 
		char sTemp[PARAMETER_LIMIT+50+COMMAND_LIMIT+2]={'\0'} ;
		fgets(sTemp, PARAMETER_LIMIT+50+COMMAND_LIMIT+2,fichier) ;
		sscanf(sTemp, "%s %s %s\n", &cmd[i].nomCommande, &cmd[i].option, &cmd[i].parametre);
		printf ("%s %s %s\n",cmd[i].nomCommande, cmd[i].option, cmd[i].parametre);
 
		i++;
	}
 
	return 0;
}

Tout est dans l'ordre, mais il complète les chaînes par des caractaires spéciaux
Nico_stras est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/01/2007, 20h46   #3
Membre du Club
 
Inscription : juin 2005
Messages : 220
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 220
Points : 47
Points : 47
Salut et merci pour la réponse !!

En effet, y'a du mieux !! Mais c'est bizare cette histoire de caractère spéciaux, j'ai remarqué que ça le faisait que sur des petites lignes comme "ls" mais quand les lignes sont plus grandes du style "ls -i /proc" là ça marche nickel...

Tu sais pas d'où sa peut venir ?
soad029 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 00h11   #4
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par Nico_stras
Code :
1
2
3
4
5
6
7
8
9
10
11
 
#define COMMAND_LIMIT  20
#define PARAMETER_LIMIT  20
	typedef struct
{
	char nomCommande[COMMAND_LIMIT];
	char option[50];
	char parametre[PARAMETER_LIMIT];
} Commande;
<...>
		sscanf(sTemp, "%s %s %s\n", &cmd[i].nomCommande, &cmd[i].option, &cmd[i].parametre);
Tout est dans l'ordre, mais il complète les chaînes par des caractaires spéciaux
Pas de & avec les tableaux...
Code :
1
2
3
4
 
      sscanf(sTemp, "%s %s %s\n", cmd[i].nomCommande
                                , cmd[i].option
                                , cmd[i].parametre);
Quand au \n final, je ne sais pas si c'est correct.

Il serait particulièrement bien venu de contrôler le code retour (nombre de conversions réussies...)

et #include "stdafx.h", c'est du pur Microsoft. Pas portable du tout... Mettre les headers nécessaires explicitement.
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 07h20   #5
Membre du Club
 
Inscription : septembre 2005
Messages : 151
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

Informations forums :
Inscription : septembre 2005
Messages : 151
Points : 48
Points : 48
Envoyer un message via MSN à Nico_stras
Excuse pour le stdafx. J'ai testé le code sous Windows.

Tout a fait juste aussi pour le '&'

Par contre, le
Code :
sscanf(sTemp, "%s %s %s\n", &cmd[i].nomCommande, &cmd[i].option, &cmd[i].parametre);
marche aussi. Pourquoi ?


Autre écriture correcte :
Code :
sscanf(sTemp, "%s %s %s\n", (cmd+i)->nomCommande, (cmd+i)->option, (cmd+i)->parametre);
Le '\n' est inutile aussi
Nico_stras est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 12h29   #6
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par Nico_stras
Par contre, le
Code :
sscanf(sTemp, "%s %s %s\n", &cmd[i].nomCommande, &cmd[i].option, &cmd[i].parametre);
marche aussi. Pourquoi ?
Parce que l'adresse du tableau et l'adresse du premier élément du tableau sont confondues :

http://emmanuel-delahaye.developpez.....htm#param_tab

Mais c'est incorrect parce que le type est différent. Ton compilateur ne dit rien ?

http://emmanuel-delahaye.developpez....tm#cfg_compilo
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 13h54   #7
Membre du Club
 
Inscription : septembre 2005
Messages : 151
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

Informations forums :
Inscription : septembre 2005
Messages : 151
Points : 48
Points : 48
Envoyer un message via MSN à Nico_stras
D'acord, c'est confondu, mais là, c'est l'adresse de l'adresse de donc de type char**

Le compilo (VS 2005) ne dit rien. Mais je suis d'accord avec toi que ce n'est pas correct
Nico_stras est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 15h36   #8
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par Nico_stras
D'acord, c'est confondu, mais là, c'est l'adresse de l'adresse de donc de type char**
Non. de type (char *) [TAILLE]
Citation:
Le compilo (VS 2005) ne dit rien. Mais je suis d'accord avec toi que ce n'est pas correct
A ma connaissance, seul gcc en mode -Wall -Wextra voit ce genre de défaut avec printf...

Par contre, ton compilateur devrait être sensible à ça :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
int main (void)
{
   char s[10];
 
   char *pa = s;                /* OK */
   char *pb = &s;               /* incorrect */
   char (*pc)[10] = &s;         /* OK */
   char **pd = &s;              /* incorrect */
 
   return 0;
}
gcc :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
Project   : Forums
Compiler  : GNU GCC Compiler (called directly)
Directory : C:\dev\forums2\
--------------------------------------------------------------------------------
Switching to target: default
Compiling: main.c
main.c: In function `main':
main.c:6: warning: initialization from incompatible pointer type
main.c:8: warning: initialization from incompatible pointer type
main.c:5: warning: unused variable `pa'
main.c:6: warning: unused variable `pb'
main.c:7: warning: unused variable `pc'
main.c:8: warning: unused variable `pd'
Linking console executable: console.exe
Process terminated with status 0 (0 minutes, 1 seconds)
0 errors, 6 warnings
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 19h18   #9
Membre du Club
 
Inscription : juin 2005
Messages : 220
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 220
Points : 47
Points : 47
En effet, après les remarques apportées par Emmanuel cela marche fortement bien !! Donc un grand merci à vous deux !

Par contre je m'intéroge sur un truc, pourquoi quand je fais :

Code :
1
2
3
 
char cmd[200][200];
sscanf(sTemp, "%s %s %s", cmd[i][0], cmd[i][1], cmd[i][2]);
ça me rempli que des valeurs null, pourtant une case d'un tableau à 2 dimensions équivaut bien à une case d'un tableau de structure, non ?
soad029 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 19h32   #10
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par soad029
Par contre je m'intéroge sur un truc, pourquoi quand je fais :
Code :
1
2
3
 
char cmd[200][200];
sscanf(sTemp, "%s %s %s", cmd[i][0], cmd[i][1], cmd[i][2]);
ça me rempli que des valeurs null, pourtant une case d'un tableau à 2 dimensions équivaut bien à une case d'un tableau de structure, non ?
40000 char en mémoire auto, ça se fait pas...
quick'n dirty :
Code :
1
2
3
 
   static char cmd[200][200];
   sscanf(sTemp, "%s %s %s", cmd[i][0], cmd[i][1], cmd[i][2]);
Mais quel est le type de cmd[i][0] ? Tu trouves que ça ressemble à un char * ?

Encore une fois, ce genre de chose est détectée par gcc, mais si tu as un doute, fait un essai 'en dur' comme je te l'ai déjà montré. On ne sera pas toujours là pour tout faire à ta place... :
Code :
1
2
3
4
 
char s[3][10];
 
char *p = s[1][2];
ça devrait faire réagir ton compilateur...
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 19h39   #11
Membre du Club
 
Inscription : septembre 2005
Messages : 151
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

Informations forums :
Inscription : septembre 2005
Messages : 151
Points : 48
Points : 48
Envoyer un message via MSN à Nico_stras
Tu m'as devancé Manu ...

Quel con Microsoft !!

Code :
1
2
3
4
5
6
7
8
int main(int argc, _TCHAR* argv[])
{
	int i=1 ;
	char cmd[200][200];     // Tableau à 2 dimensions de CARACTERES
	char* sTemp="kkjhu jjj gggg" ;
	sscanf(sTemp, "%s %s %s", cmd[i][0], cmd[i][1], cmd[i][2]); 
	return 0;
}
0 erreur, 0 Warning

J'en déduis qu'il faut éviter Microsoft VS pour faire des programmes de base comme celui-ci !!!

_________________________________________

Je laisse soad029 trouver son erreur
Nico_stras est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 19h55   #12
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par Nico_stras
J'en déduis qu'il faut éviter Microsoft VS pour faire des programmes de base comme celui-ci !!!
Bah, je te rassure, avec Borland, c'est pareil. C'est plutôt gcc qui est exceptionnel, en ce sens qu'il analyse les chaines de formatage de *printf() et de *scanf(), alors que ces fonctions font partie de la bibliothèque et non du noyau du langage (mais elles font quand même partie du langage).
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/01/2007, 20h44   #13
Rédacteur
 
Avatar de Emmanuel Delahaye
 
Inscription : décembre 2003
Messages : 14 502
Détails du profil
Informations personnelles :
Âge : 55
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : décembre 2003
Messages : 14 502
Points : 18 103
Points : 18 103
Citation:
Envoyé par Nico_stras
Tu connais un petit IDE léger avec GCC ?
je sais ... Je ne suis pas au bon endroit pour demander ça
Nous sommes très nombreux à utiliser Code::Blocks. C'est suffisamment léger pour mon portable (Celeron M80, RAM 256 Mo, XP...)
__________________
Pas de Wi-Fi à la maison : CPL

Des infos sur la programmation et le langage C:
http://bien-programmer.blogspot.com/
http://www.bien-programmer.fr/
http://bien-programmer.forum-actif.net/forum.htm
Emmanuel Delahaye est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h35.


 
 
 
 
Partenaires

Hébergement Web