我需要比较一个由fdin从stdin获取的字符串,以及另一个通过fscanf从文件中获取的字符串(并使用fprintf写入文件)。我必须使用这两个函数从stdin和文件中读取。 我怎么能这样做? 因为我看到fgets也存储“\ 0”字节,但是fscanf no。
这是代码:
#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 :(得分: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) {
:
答案 1 :(得分:0)
我怎么能这样做?因为我看到fgets也存储“\ 0”字节,但是fscanf no。
我只是阅读了fscanf的文档并对其进行了测试,这很好用:
#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;
}
答案 2 :(得分:0)
scanf或fscanf会终止换行符或空格字符串上的字符串。其中fgets等到\ n。
因此,如果你打电话
fscanf(stdin, "%s", str);
vs
fgets(str);
并且文件包含“Hello there”
fscanf只会包含“Hello”,因为fgets会返回整个字符串