C:sscanf问题

时间:2010-07-28 18:32:34

标签: c unicode scanf

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

2
A 10 5
B 31 2
C 6 6

我想读取变量中的第一个行号 并读取每个行的空格分隔的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行! 在第2行它什么都没有存储! 当我在调试器中检查时,文件中有一些奇怪的字符(\ 342 \ 200 \ 252),我不知道它们来自哪里!?

有什么问题?

由于

4 个答案:

答案 0 :(得分:2)

嗯......我希望看到 last 行出现问题,但是随便看看为什么你应该在其他地方遇到问题。 OTOH,至少当我解决你(试图)检测文件结尾的明显问题时,它似乎对我来说很好:

#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

答案 1 :(得分:2)

以下代码适用于我:

#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;
}

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

答案 2 :(得分:1)

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

fgets进入tmp之后,请尝试将其打印出来,看看它是否符合您的预期。

您应该存储并显示sscanf的返回值,以查看它是否成功。

答案 3 :(得分:1)

您看到的字符(\ 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);
}

但是,由于其他人已经发布了几种适合他们而不适合你的方法,输入文件肯定是错误的候选者。