fscanf如何知道这是行的结束?

时间:2013-12-21 16:46:29

标签: c

如果文件中的字符串是:

,我从文件中读取字符串
 "User1 User2 User3 User4 User5"
 "test1"

我想只读取文件的第一行,我的代码是:

 if (in_fp != NULL)
 {
   while (fscanf(in_fp, "%s", &user)!=EOF)
    {
      temp = (char*)malloc(sizeof user);
      strcpy(temp,user);
     }
 fclose (in_fp);
 }

但问题是fscanf还从文本文件中读取“test1”,我需要知道如何让他知道这是行的结束,我需要在我的代码中修复什么? 我知道fgets ,但我想分别阅读每个用户

3 个答案:

答案 0 :(得分:5)

一种方式

    if (in_fp != NULL){
        while (fscanf(in_fp, "%s%c", user, &ch)==2){
            temp = (char*)malloc(sizeof user);
            strcpy(temp, user);
            //do something
            printf("%s\n", user);
            free(temp);
            if(ch == '\n')
                break;
        }
        fclose (in_fp);
    }

答案 1 :(得分:2)

使用fscanf("%s")和变体格式是解决此任务的难题。

%s不加选择地消耗包括' ''\n'在内的领先空白,但OP明确地将这2个用作用户名分隔符和记录分隔符。读取一行更好,使用fgets()然后解析缓冲区读取。

OP担心未知的线路长度。虽然最好不限制代码只能使用短行,但设计代码以使用无穷无尽的行也存在问题。过长的行增加了错误数据或恶意攻击的迹象。如果数据文件试图超过它,最好分配一个大缓冲区并优雅地抱怨。

size_t N = 4096;
char *buffer = malloc(N);
if (buffer == NULL) ...
while (fgets(buffer, N, in_fp) != NULL) {
  size_t Len = strlen(buffer);
  if (Len == 0 || buffer[Len-1] != '\n) {
    HandleUnacceptbaleBuffer();
  }
  // parse buffer via sscanf, strtok, etc.
  char *p = buffer;
  int n
  while (1 == sscanf(p, "%s%n", &user, &n)) {
    Handle(user);
    p += n;
  }
}
free (buffer);

答案 2 :(得分:0)

你没有。

您也不想使用scanf()。避免像瘟疫一样。

如果您想阅读行,请使用fgets()。 (即使你不想阅读线条,仍然使用它,仍然比scanf()好得多。)


我看到了“但我想分别阅读每个单词”问题传入。所以,你在这里:

char buf[LINE_MAX];
if (!fgets(buf, sizeof buf, stdin)) {
    // handle error
}

char *p = buf, *s = p;
while (p) {
    p = strtok_r(s, " ", &s);
    // do stuff with `p` if it's not NULL
}

此外, do NOT cast the return value of malloc()!