Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 16/03/2010, à 01:59

Fake

[Résolu] [C] filtre d'une des variables obtenue par sscanf

Bonjour,

Je cherche à faire la lecture d'un fichier où l'on a sauvegardé la configuration de mon futur logiciel.

J'ai fait quelque chose qui marche pour la lecture mais maintenant il faut sauver la config lue dans une série de variables.

Voilà où j'en suis :

#include <stdio.h>

int main()
{
	// variables qui contiendront la configuration
	char *wordlistfont;
	char *wordcopyfont;
	// lecture du fichier
	FILE *conffile;
	if(conffile = fopen("copie.conf", "r"))
	{
		char line[256];
		char prop[256];
		char value[256];
		// On mange toute la ligne, on décide si c'est intéressant et si oui on trie la propriété et la valeur
		while(fgets(line, sizeof line, conffile))
		{
			printf("%s", line);
			if(line[0] == 'p')
			{
				sscanf(line, "p%s = %256c", prop, value);
				printf("%s \n", prop);
				printf("%s \n", value);
				
				if(prop == "wordlistfont"){wordlistfont = value ;}
				if(prop == "wordcopyfont"){wordcopyfont = value ;}
			}
		}
		fclose(conffile);
	}
	printf("%s \n", wordlistfont);
	printf("%s \n", wordcopyfont);
}

avec un fichier copie.conf qui est :

# Configuration file for Copie software

# Il est possible de modifier les valeurs des propriétés
#
# mais
#
# NE JAMAIS MODIFIER LE NOM DES PROPRIÉTÉS DE LA CONFIGURATION
#
# le programme ne pourrait plus charger la configuration 


# Font description string for word to copy : <fontname> <style> <size> 
# pwordlistfont
pwordlistfont = Sans Bold 20

# Font description string for copy text zone : <fontname> <style> <size> 
# pwordcopyfont
pwordcopyfont = Sans Bold 17

ça compile bien mais vu ce que rendent les printf, les valeurs enregistrées dans les variables :

# Configuration file for Copie software

# Il est possible de modifier les valeurs des propriétés
#
# mais
#
# NE JAMAIS MODIFIER LE NOM DES PROPRIÉTÉS DE LA CONFIGURATION
#
# le programme ne pourrait plus charger la configuration 


# Font description string for word to copy : <fontname> <style> <size> 
# pwordlistfont
pwordlistfont = Sans Bold 20
wordlistfont 
Sans Bold 20
 

# Font description string for copy text zone : <fontname> <style> <size> 
# pwordcopyfont
pwordcopyfont = Sans Bold 17
wordcopyfont 
Sans Bold 17
 
����; 
(null)

Voila je suppose que le problème est dans les types des variables prop et value, mais je ne trouve rien qui marche...

Bon si vous avez d'autres méthodes pour lire des fichiers de conf formatés autrement, je suis preneur mais j'ai cherché et rien trouvé de tel comme bout de code sur le net...

Dernière modification par Fake (Le 16/03/2010, à 17:25)

Hors ligne

#2 Le 16/03/2010, à 08:25

grim7reaper

Re : [Résolu] [C] filtre d'une des variables obtenue par sscanf

Salut,

À première vu tu as du mal avec les chaînes de caractère en C.

        char line[256];
        char prop[256];
        char value[256];

Si tu veux lire au maximum 256 caractères la taille doit être 257 car il faut tenir compte du "null character" qui termine la chaîne. Sans ça tu vas au devant de gros ennui.

sscanf(line, "p%s = %256c", prop, value);

Tu veux créer une chaîne de caractère en lisant, pas un tableau de char. Il faut donc utiliser

%256[^\n]

(le comportement de scanf le faisant stopper au premier espace rencontré, il est nécessaire de passer par une chaîne de format de ce type pour arriver à lire la ligne entière, pour plus d'info => man scanf dans une console ou sur internet).
et non pas

%256c

(sinon tu auras des problèmes pour utiliser les fonctions de manipulation de chaîne).

if(prop == "wordlistfont"){wordlistfont = value ;}
if(prop == "wordcopyfont"){wordcopyfont = value ;}

Oulala, voilà ce qui me fait dire que tu ne maîtrise pas les chaînes de caractère en C. Retiens bien : On ne peut pas comparer 2 chaînes avec l'opérateur ==. Ici tu compare l'adresse de début de tes chaînes qui sont forcément différentes dans ce cas.
Pour faire ce que tu souhaites il faut utiliser la fonction strcmp.

Voilà comme ça tu n'afficheras pas des variables dont le contenu est indéterminée et ton programme devrait mieux s'exécuter.

Dernière modification par grim7reaper (Le 16/03/2010, à 08:30)

Hors ligne

#3 Le 16/03/2010, à 10:54

Fake

Re : [Résolu] [C] filtre d'une des variables obtenue par sscanf

Super Merci, je vais essayer tout ça et relire (pour la n-ieme fois, j'ai bien parcouru déja pas mal de fois des docs sur les chaines et scanf et le tralala, mais c'est pas évident... ) les mans et les poly que j'ai sur le C.

Ils ont pas été bien malin quand même d'oublier les strings dans le language C... :-)

Hors ligne

#4 Le 16/03/2010, à 13:20

grim7reaper

Re : [Résolu] [C] filtre d'une des variables obtenue par sscanf

N'oublie pas de passer le sujet en résolu wink.

Sinon, pour le coup des strings, disons que le C est un vieux langage donc ce n'est pas étonnant ^^ (au pire ça se code pas trop mal).

Hors ligne

#5 Le 16/03/2010, à 15:56

Fake

Re : [Résolu] [C] filtre d'une des variables obtenue par sscanf

En fait ça ne marche pas tout a fait encore...

J'ai tenu compte de ce que tu m'avait dit et j'ai fait comme ça :

#include <stdio.h>

int main()
{
	char *wordlistfont;
	char *wordcopyfont;
	FILE *conffile;
	if(conffile = fopen("copie.conf", "r"))
	{
		char line[256];
		char prop[256];
		char value[256];
		while(fgets(line, sizeof line, conffile))
		{
			printf("%s", line);
			if(line[0] == 'p')
			{
				sscanf(line, "p%s = %255[^\n]", prop, value);
				if(! strcmp(prop, "wordlistfont")) 
					wordlistfont = value ;
				if(! strcmp(prop, "wordcopyfont"))
					wordcopyfont = value ;
			}
		}
		fclose(conffile);
	}
	printf("%s \n", wordlistfont);
	printf("%s \n", wordcopyfont);
}

Mais les variables wordlistfont et wordcopyfont contiennent toutes les deux la même valeur, correspondant à la deuxième propriété lue...
J'ai beau chercher, je vois pas très bien d'où ça peut venir, à part si peut être, le strcmp renvoie une erreur quelconque ?
Pourtant des printf me montrent que j'ai bien les bonnes valeurs dans les bonnes variables juste avant les strcmp...

Hors ligne

#6 Le 16/03/2010, à 17:17

Fake

Re : [Résolu] [C] filtre d'une des variables obtenue par sscanf

Je me réponds à moi même je pense que je sais pourquoi ca ne marchait pas :
J'affecte les chaines mais du coup mes deux pointeurs pointent au même endroit et j'ai la même valeur au final...

Du coup il doit falloir utiliser strcpy sans doute pour copier le contenu des chaines.
Jusque là ca me donne une erreur de segmentation au deuxième passage sur les tests if(! strcmp...).

Hors ligne

#7 Le 16/03/2010, à 17:25

Fake

Re : [Résolu] [C] filtre d'une des variables obtenue par sscanf

Désolé pour les 3 posts à la suite mais voilà ca marche, il fallait donner une taille définie aux varables contenant les valeurs.
Je suppose que copier une chaine char *[256] dans une chaine char* ne marche pas a tous les coups et quelque part ca semble logique, vu qu'il n'est pas sensé réserver la place pour les potentiels 256 charactères...

Voila merci grim7reaper pour tes précisions sur le strings qui m'ont bien servies :-)

Et voila le code qui marche quand même :

#include <stdio.h>
#include <string.h>

int main()
{
	char wordlistfont[256];
	char wordcopyfont[256];
	FILE *conffile;
	if(conffile = fopen("copie.conf", "r"))
	{
		char line[256];
		char prop[256];
		char value[256];
		while(fgets(line, sizeof line, conffile))
		{
			if(sscanf(line, "p%s = %255[^\n]", prop, value))
			{
				if(strcmp(prop, "wordcopyfont") == 0)
						strcpy(wordcopyfont, value) ;
				if(strcmp(prop, "wordlistfont") == 0) 
						strcpy(wordlistfont, value) ;
			}
		}
		fclose(conffile);
	}
}

Hors ligne

#8 Le 16/03/2010, à 20:56

grim7reaper

Re : [Résolu] [C] filtre d'une des variables obtenue par sscanf

Fake a écrit :

Je me réponds à moi même je pense que je sais pourquoi ca ne marchait pas :
J'affecte les chaines mais du coup mes deux pointeurs pointent au même endroit et j'ai la même valeur au final...

C'est exactement ça, tu as bien compris le truc.

Fake a écrit :

Je suppose que copier une chaine char *[256] dans une chaine char* ne marche pas a tous les coups et quelque part ca semble logique, vu qu'il n'est pas sensé réserver la place pour les potentiels 256 charactères...

Là encore, tu as bien saisie le problème. Un char* est un pointeur mais aucune zone mémoire ne lui est réservé (on peut utiliser l'allocation dynamique pour cela). Le fait de créer un tableau de taille adéquate résous le problème.

Dernière modification par grim7reaper (Le 16/03/2010, à 20:56)

Hors ligne