2012-09-05 33 views
0

我需要比較stdin從fgets獲取的字符串與fscanf從文件獲取的另一個(並使用fprintf寫入文件)。我必須使用這兩個函數來從標準輸入和文件讀取。 我該怎麼做? ,因爲我已經看到fgets存儲「\ 0」字節,但是fscanf沒有。比較使用fgets和fscanf獲取的字符串

這是代碼:

#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

哦,是的是的。 – 2012-09-05 19:05:48

回答

0

我可怎麼辦呢?因爲我已經看到fgets存儲「\ 0」字節,但是fscanf沒有。

我只是閱讀文檔的fscanf和測試它,這工作得很好:當與%s通過

#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

那麼如果'fscanf'失敗,你會將垃圾傳遞給'strcmp'? – cnicutar

+0

@cnicutar nope,那不是目標。如果'fscanf()'*不能終止字符串,那麼我會通過垃圾郵件。 – 2012-09-05 19:24:40

+0

我指的是初始化。如果fscanf失敗,它將使'str'保持不變。而'str'不是以0結尾的。 – cnicutar

0

scanf或終止的fscanf上換行或空格字符的字符串。在fgets等到\ n之前。

因此,如果你打電話

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

vs 

fgets(str); 

該文件包含「你好」

的fscanf將只包含「你好」,其中作爲與fgets將返回整個字符串

2

大量的潛在問題這裏取決於你想要做什麼

  • fgets讀取一行(最多包括換行符),而fscanf(.."%s"..)讀取由空白分隔的令牌。根本不是一回事。

  • fscanf(.."%s"..)不檢查您給它寫入的緩衝區的邊界。你真的想要fscanf(.."%19s"..)確保它不會寫入超過20個字節(包括NUL終止符)到你的20字節緩衝區。

  • while(!feof(fp))幾乎總是錯的。 feof不會告訴你,如果你在文件末尾,它會告訴你是否試圖讀取文件末尾。因此,如果您剛剛閱讀文件末尾並且尚未讀取它,feof將返回false,但下一次讀取將失敗。

  • 你真的想檢查fscanf的返回值,以確保它讀取你想要它讀取的內容(並且實際上寫了一些東西到輸出緩衝區中)。結合上面的內容,這意味着你可能希望你的循環是這樣的:

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

固定答案:-) – cnicutar