繁体   English   中英

使用fscanf()时不了解C格式说明符

[英]Not understanding the C format specifiers when using fscanf()

因此,我正在读取以下格式的文本文件:

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[^ ...尝试读取用空格分隔的字符串,后跟字符[ ,然后是字符^ 。”由于字符串将始终以空格结尾,因此下一个字符将始终为空格,这将不会。 t匹配[ ,格式说明符的其余部分将不匹配。

  • 始终检查fscanf的返回值,以确保您已阅读所做的所有操作。 如果返回值错误,请进行诊断。

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

因此,您需要的是:

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

我不确定您是否要使用空格定界符[^]。 fscanf已经将空格解析为默认字符串。 试试这个,看看字符串是否被正确解析:

fscanf(fp, "%s %s %s[^\n]", cp->name, cp->lat, cp-lng);  

输出应导致:

cp->name ---- ABC
cp->lat ----- 51.555
cp->lng ----- 31.555

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM