代码之家  ›  专栏  ›  技术社区  ›  Ariyan

C: sscanf问题

  •  1
  • Ariyan  · 技术社区  · 16 年前

    我有一个这样的文本文件:

    2个
    甲105
    B 312年
    C6类

    我想读取变量中的第一个行号
    并读取每一行用空格分隔的列表,其中包含3个变量中的3个值。 我写了这段代码:

    iF=fopen(fileName,"r");
    fgets(tmp,255,iF);
    sscanf(tmp,"%d",&interval);
    
    while(!feof(iF)){
        cur=(P *)malloc(sizeof(P));
        fgets(tmp,255,iF);
        sscanf(tmp,"%c %d %d",&Name,&AT,&ET);
        cur->jobName=Name;
        cur->arrivalTime=AT;
        cur->execTime=ET;
        add_to_list(head,cur);
    }
    

    它适用于1、3、4号线,但不适用于2号线! 在第二行里什么都没有! 当我签入调试器时,文件(\342\200\252)中有一些奇怪的字符,我不知道它们来自哪里!?

    怎么了?

    谢谢

    4 回复  |  直到 16 年前
        1
  •  2
  •   Jerry Coffin    16 年前

    嗯…我希望看到 最后的 行,但不明白为什么你应该有其他问题。哦,至少当我解决了你(试图)检测文件结尾的明显问题时,它对我来说似乎很好:

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct P { 
        char jobName;
        int arrivalTime;
        int execTime;
    } P;
    
    void show_P(P const *r) { 
        printf("Name: %c, Arrival Time: %d, Execute Time: %d\n", r->jobName, r->arrivalTime, r->execTime);
    }
    
    int main() {
        int interval;
        char Name;
        int AT, ET;
        char tmp[256];
    
        FILE *iF=fopen("stupid_input.txt","r");
    
        fgets(tmp,255,iF);
        sscanf(tmp,"%d",&interval);
    
        while(fgets(tmp, 255, iF)){
            P *cur=malloc(sizeof(P));
            sscanf(tmp,"%c %d %d",&Name,&AT,&ET);
            cur->jobName=Name;
            cur->arrivalTime=AT;
            cur->execTime=ET;
            show_P(cur);
        }
        return 0;
    }
    

    结果:

    Name: A, Arrival Time: 10, Execute Time: 5
    Name: B, Arrival Time: 31, Execute Time: 2
    Name: C, Arrival Time: 6, Execute Time: 6
    
        2
  •  2
  •   Roland Illig    16 年前

    以下代码对我有效:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        const char *fileName = "data.txt";
        FILE *iF;
        int interval;
        char Name[256], tmp[256];
        int AT, ET;
    
        iF = fopen(fileName, "r");
        if (fgets(tmp, 255, iF) == NULL)
            goto error;
        if (sscanf(tmp, "%d", &interval) != 1)
            goto error;
    
        while (fgets(tmp, 255, iF) != NULL) {
            if (sscanf(tmp, "%c %d %d", Name, &AT, &ET) != 3)
                goto error;
            fprintf(stdout, "%s, %d, %d\n", Name, AT, ET);
        }
        return 0;
    
    error:
        fprintf(stderr, "error while reading from the file.\n");
        return 1;
    }
    

    请注意有多少代码专用于错误处理。那是必要的。

        3
  •  1
  •   abelenky    16 年前

    要调试此问题,请执行几个简单的调试步骤:

    在你之后 fgets 进入之内 tmp ,请尝试打印出来,看看它是否符合您的期望。

    您应该存储并显示 sscanf 看看它是否成功。

        4
  •  1
  •   Brandon Horsley    16 年前

    您看到的字符(\342\200\252)是226、128和170的八进制。它们不会映射到您在输入文件中意外键入的字符。我的建议是用十六进制编辑器检查输入文件,看看里面是否有垃圾。

    如果不是,您可以尝试更改读取文件的方式,以查看代码中是否存在故障,例如,您可以尝试fscanf(通常不首选此选项):

    FILE *iF = fopen("input.txt", "r");
    if (fscanf(iF, "%d\n", &interval) != 1)
    {
      fprintf(stderr, "Error parsing interval.\n");
      fclose(iF);
      return;
    }
    
    while (! feof(iF))
    {
       cur = (P *)malloc(sizeof(P));
       if (fscanf(iF, "%c %d %u\n",&cur->jobName, &cur->arrivalTime, &cur->execTime) != 3)
       {
         fprintf(stderr, "Error parsing line.\n");
         free(cur);
         break;
       }
       add_to_list(head,cur);
    }
    

    但是,由于其他人已经发布了一些对他们有效而不是对您有效的方法,因此输入文件肯定是可能出错的。