我在使用sscanf函数时犯了错误吗?

时间:2014-12-30 08:01:40

标签: c

我想通过sscanf从hoge.txt获取数据。(见下文)

但我得到了好奇的结果。

我无法理解为什么会这样。

请帮忙。

我通过Borland C / C ++ 5.5.1为Win32编译和链接 - 如果有帮助的话。

#include<stdio.h>
#include<string.h>

int main(int argc, char *argv[]){

    FILE *fp;
    char buf[100];
    char name1[100];
    char name2[100];
    int distance1;
    int distance2;

    /* file open */
    fp = fopen(argv[1],"r");
    if(fp == NULL){
       return -1;
    }

    /* get a line */
    fgets(buf,100,fp);

    /* change \n to \0 */
    strtok(buf,"\n");

    /* get values from buf */
    sscanf(buf,"%s,%d; %s,%d;",name1,&distance1,name2,&distance2);

    /* for tests */
    printf("%s\n",name1);
    printf("%s\n",name2);
    printf("%d\n",distance1);
    printf("%d\n",distance2);

    return 0;
}

【hoge.txt】※只是一行

Ramytdb,2683; Voclqmb,5236;

【结果】

Ramytdb,2683; ワ升レWD 1 256

2 个答案:

答案 0 :(得分:9)

使用

sscanf(buf,"%[^,],%d; %[^,],%d;",name1,&distance1,name2,&distance2);

而不是

sscanf(buf,"%s,%d; %s,%d;",name1,&distance1,name2,&distance2);

您的代码失败,因为%s在看到,时没有停止扫描。它在遇到\n或空格时停止扫描。在您的情况下,它扫描Ramytdb,2683;并停止,因为下一个字符是空格。这会导致事情陷入困境。

您还可以通过使用

限制要读取的字符数来提供更多安全性
sscanf(buf,"%99[^,],%d; %99[^,],%d;",name1,&distance1,name2,&distance2);

请注意,字符串末尾的\0字符需要一个空格,这就是我使用99而不是100的原因。

您可以通过检查sscanf的结果来进一步改进它。sscanf返回填充的变量数。因此,使用

检查它是否返回4
if(sscanf(buf,"%[^,],%d; %[^,],%d;",name1,&distance1,name2,&distance2)==4)
  //sscanf was successful
else
  //sscanf was not successful

您还可以在%*c的末尾添加sscanf。这会读取一个角色并丢弃它。如果文件中行末尾有\n个字符,这可能很有用。

答案 1 :(得分:2)

从手册页转换

  

取值

     

匹配一系列非空白字符;下一个指针   必须是一个指向字符数组的指针,该数组足够长以容纳   输入序列和添加的终止空字节('\ 0')   自动。输入字符串在空白处或最大处停止   字段宽度,以先到者为准。

因此,第一个%s将读取尽可能多的字符,即非白色空格。那将包括逗号。因此,通过检查返回值,您会注意到这一点。

你需要使用另一种转换 - 也许是']'?浏览网页http://linux.die.net/man/3/scanf将帮助您做出决定