2012-09-05 2 views
0

J'ai besoin de comparer une chaîne acquise à partir de stdin par fgets, avec une autre acquise à partir du fichier par fscanf (et écrire sur le fichier avec fprintf). Je dois nécessairement utiliser les deux fonctions pour lire depuis stdin et le fichier. Comment je peux faire ça? parce que j'ai vu que fgets stocke aussi "\ 0" octet, mais fscanf non.comparer chaîne acquise avec fgets et fscanf

Voici le code:

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

typedef struct asd { 
    char a[20]; 
    char b[20]; 
} struttura; 


void stampa_file() { 
struttura *tmp = NULL; 
struttura *letto = NULL; 
FILE *file; 

tmp = (struttura *)malloc(sizeof(struttura)); 
letto = (struttura *)malloc(sizeof(struttura)); 
file = fopen("nuovoFile", "r"); 
printf("compare:\n");\ 
fgets(letto->a, sizeof(letto->a), stdin); 
fgets(letto->b, sizeof(letto->b), stdin); 
while(!feof(file)) { 
    fscanf(file, "%s %s\n", tmp->a, tmp->b); 
    printf("a: %s, b: %s\n", tmp->a, tmp->b); 
    if(strcmp(letto->a, tmp->a) == 0 && strcmp(letto->b, tmp->b)) { 
     printf("find matching\n"); 
    } 
} 
free(tmp); 
free(letto); 
} 

int main() { 
struttura *s = NULL; 
FILE *file; 

s = (struttura *)malloc(sizeof(struttura)); 

file = fopen("nuovoFile", "a+"); 
printf(""); 
fgets(s->a, sizeof(s->a), stdin); 
printf(""); 
fgets(s->b, sizeof(s->b), stdin); 
fprintf(file, "%s%s\n", s->a, s->b); 
fclose(file); 
stampa_file(); 

free(s); 
return 0; 
} 
+0

Oh oui, il le fait. –

Répondre

0

Comment puis-je faire? parce que j'ai vu que fgets stocke aussi "\ 0" octet, mais fscanf non.

Je viens lire la documentation fscanf et testé, et cela a bien fonctionné:

#include <stdio.h> 

int main() 
{ 
    char str[100] = { 1 }; // intentionally initialized to nonzero junk 
    fscanf(stdin, "%s", str); 
    if (strcmp(str, "H2CO3") == 0) 
     printf("This is me\n"); 
    else 
     printf("This is not me\n"); 
    return 0; 
} 
+0

Donc, si 'fscanf' échoue, vous passerez le 'junk' dans' strcmp'? – cnicutar

+0

@cnicutar non, ce n'est pas le but. Si 'fscanf()' * ne termine pas NUL * la chaîne, alors je passe le junk. –

+0

Je faisais référence à l'initialisation. Si fscanf échoue, il laissera 'str' inchangé. Et 'str' n'est pas terminé par 0. – cnicutar

0

scanf ou fscanf lorsqu'il est passé avec% s met fin à la chaîne ou l'espace sur newline omble chevalier. Où comme fgets attend le \ n.

Par conséquent, si vous appelez

fscanf(stdin, "%s", str); 

vs 

fgets(str); 

et le fichier contient « Bonjour »

fscanf ne contiendrait « Bonjour » où fgets reviendriez la chaîne entière

2

Beaucoup de problèmes potentiels ici en fonction de ce que vous essayez de faire

  • fgets lit une ligne (jusqu'à et y compris un saut de ligne) tandis que fscanf(.."%s"..) lit un jeton délimité par des espaces. Pas du tout la même chose.

  • fscanf(.."%s"..) ne vérifie pas les limites sur le tampon que vous lui donnez à écrire. Vous voulez vraiment fscanf(.."%19s"..) pour vous assurer qu'il n'écrit pas plus de 20 octets (y compris le terminateur NUL) dans votre tampon de 20 octets.

  • while(!feof(fp)) est presque toujours faux. feof ne vous dit pas si vous êtes à la fin du fichier, il vous indique si vous avez essayé de lire après la fin du fichier. Donc, si vous venez de lire jusqu'à la fin du fichier et que vous ne l'avez pas encore lu, feof retournera false, mais la lecture suivante échouera.

  • Vous voulez vraiment vérifier la valeur de retour de fscanf pour vous assurer qu'il lit ce que vous vouliez qu'il lise (et réellement écrit quelque chose dans les tampons de sortie.) Combiné avec ce qui précède, cela signifie que vous voulez probablement que votre boucle quelque chose comme:

    while (fscanf(fp, "%19s%19s", tmp->a, tmp->b) == 2) { 
         : 
    
+0

Réponse solide :-) – cnicutar