2012-09-05 27 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