gpt4 book ai didi

c - 使用 fscanf() 时不理解 C 格式说明符

转载 作者:行者123 更新时间:2023-11-30 15:26:15 26 4
gpt4 key购买 nike

所以我正在读取以下格式的文本文件:

ABC 51.555 31.555
DEF 23.445 45.345

我正在尝试使用 fscanf() 来解析数据,因为该文件可能会增大或缩小,因此它的加载方式需要是动态的,因此我使用 malloc 并且我也想将其存储在下面的结构中。我认为问题在于空格,甚至可能没有正确编写整个格式说明符。这是我的代码。

typedef struct data
{
char name[4];
char lat[7];
char lng[7];
}coords;

int main(int argc, char *argv[])
{
////////////CREATES FILE POINTER/////////
FILE* fp;
///////////CREATES MALLOC POINTER TO STORE STRUCTS/////////////
coords* cp;
//////////OPENS FILE//////////
fp = fopen(argv[1], "r");
/////////GET THE TOTAL AMMOUNT OF LINES IN THE FILE/////////
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
rewind(fp);
//////SKIPS FIRST LINE//////////
while(fgetc(fp) != (int)'\n')
{};

/////////ASSIGNS MEMORY THE SIZE OF THE FILE TO //////////
cp = malloc(sizeof(coords) * size);

//////////READS FILE AND STORES DATA///////
fscanf(fp,"%s[^ ] %s[^ ] %s[^\n]", cp->name, cp->lat, cp->lng);

printf("%s\n%lf\n%lf\n", cp->name, cp->lat, cp->lng);
fclose(fp);
return 0;
}

是的,我知道我没有包含头文件,但我有正确的 stdlib 和 stdio

更新1:我已经尝试了这两个回复,并且我在屏幕上看到了以下内容:

ABC51.555
0.000000
0.000000

为什么 51.555 没有转到结构中的下一项?谢谢

////////////////////////////////////////////////////////////////////////////////////////////////////////更新2///////////////////////////////////////////////////////////

好的,我已经修改了代码以执行以下操作。

typedef struct data
{
char name[4];
char lat[6];
char lng[6];
}coords;

int main(int argc, char *argv[])
{
////////////CREATES FILE POINTER/////////
FILE* fp;
///////////CREATES MALLOC POINTER TO STORE STRUCTS/////////////
coords* cp;
//////////OPENS FILE//////////
fp = fopen(argv[1], "r");
/////////GET THE TOTAL SIZE OF THE FILE/////////
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
long lines = -1;
rewind(fp);
//////GETS TOTAL AMMOUNT OF LINES/////////
char c;
while(c != EOF)
{
c = fgetc(fp);
if(c == '\n')
{
lines++;
}
}
rewind(fp);
////////////SKIPS FIRST LINE//////////
while(fgetc(fp) != (int)'\n')
{};
/////////ASSIGNS MEMORY THE SIZE OF THE FILE TO //////////
cp = malloc(sizeof(coords) * size);

//////////READS FILE AND STORES DATA///////
printf("Lines of text read: %d\n", lines);
fscanf(fp,"%s %s %s[^\n]", cp[0].name, cp[0].lat, cp[0].lng);
printf("%s\n", cp[0].name);


fclose(fp);
return 0;
}

现在当我尝试打印 cp[0].name;我得到了整个第一行,没有空格,就像这样。

 ABC51.55531.555

如果我打印 cp[0].lat;我明白了。

 51.55531.555

当我打印 cp[0].lng;我明白了。

 31.555

这是唯一正确的,我无法理解这种行为。为什么它会这样?所有帖子都表明(正如我首先想到的)fscanf 中的每个 %s 都会将其放入自己的变量中,而不是将它们连接起来。不管我使用点符号还是直接 -> 它仍然有相同的结果。谢谢:)

最佳答案

格式说明符"%s[^ ...尝试读取空格分隔的字符串,后跟字符 [然后是字符^ 。由于字符串始终以空格结尾,因此下一个字符始终是空格,这与 [ 不匹配。 ,并且格式说明符的其余部分都不会匹配。

  • 始终检查 fscanf 的返回值确保您阅读了您所做的所有事情。如果返回值错误,给出诊断。

  • 在读取固定大小的字符串数组时始终使用字段大小限制。

所以在你的情况下你想要的是:

if (fscanf(fp, "%3s%6s%6s", cp->name, cp->lat, cp->lng) != 3) {
fprintf(stderr, "Incorrect data in input file, exiting!\n");
abort(); }

关于c - 使用 fscanf() 时不理解 C 格式说明符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27436300/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com