有没有比我更有效的方式在C中读取格式化文件?

时间:2009-12-12 01:57:38

标签: c file-io whitespace scanf

我需要阅读看起来像这样的格式化文件。

代码:HARK

姓名:奥斯卡

MRTE:火车

目前我的代码看起来像这样。

FILE *file;
char unneeded[10];
char whitespace[2];
char actual[10];
file = fopen("scannertest.txt","r");
fscanf(file,"%s",unneeded); // this is the identifier and the colon (code:)
fscanf(file,"%[ ]",whitespace); // this takes in the white space after the colon.
fscanf(file,"%s",actual); // this is the value I actually need.
/**
* Do stuff with the actual variable
**/
fclose(file);

这种方式适合我,但我不认为为文本文件中的每一行写三个fscanf()是最好的方法,特别是因为我将在以后的循环中进行。

我尝试这样做:

fscanf(file, "%s %[ ] %s",unneeded,whitespace,real);

然而,当我尝试打印输出时,这给了我奇怪的符号。

5 个答案:

答案 0 :(得分:4)

%s scanf说明符已经忽略了空格。如果你这样做

scanf("%s%s", unneeded, actual)

输入为“Code:HARK”,unneeded将为“Code:”而actual将为“HARK”。

警告:scanf是一个麻烦的功能(安全使用“很难”)。如果您想要更安全,请指定您愿意接受每个字符串的最大字符数(记住零终结符)

scanf("%9s%9s", unneeded, actual); /* arrays defined with 10 elements */

最好使用fgets后跟sscanf

在阅读其他答案的评论后编辑

请记住*始终*检查scanf的返回值。

chk = scanf("%9s%9s", unneeded, actual);
if (chk != 2) /* error reading data */;

答案 1 :(得分:1)

在C中,文件函数使用缓冲I / O.这意味着每次调用时fscanf都不会访问磁盘,因此使用3个调用而不是1调用的性能损失应该可以忽略不计。

然而,最好的办法是让您的计划正常运行,然后如果它太慢衡量,那么性能瓶颈就会出现并先解决这些问题。尝试猜测代码的哪些部分会导致性能问题是不值得的。

答案 2 :(得分:1)

您的代码无效,因为

fscanf(file,"%s",unneeded);
fscanf(file,"%[ ]",whitespace);
fscanf(file,"%s",actual);

不做同样的事情
fscanf(file,"%s %[ ] %s", unneeded, whitespace, actual);

功能相同

fscanf(file,"%s%[ ]%s", unneeded, whitespace, actual); // No spaces in fmt string

HTH

答案 3 :(得分:0)

如果您正在寻找加速代码的方法,您可以读取整个文件或文件的缓冲区。一次读取整个块比在需要时读取数据更快。

然后,您可以在阅读的缓冲区上使用sscanf

答案 4 :(得分:0)

我是一个生病的人,不时会错过C语言的编码。我写了一些似乎有用的东西:

test.txt的内容

Code: HARK
Name: Oscar
MRTE: Train

text.c的内容

#include <stdio.h>

#define MAX_LEN 256

int main(void)
{
  FILE *file;
  char str_buf[MAX_LEN + 1]; // One extra byte needed
                             // for the null character
  char unneeded[MAX_LEN+1];
  char actual[MAX_LEN+1];


  file = fopen("test.txt","r");

  while(fgets(str_buf, MAX_LEN + 1, file) != NULL)
  {
    sscanf(str_buf, "%s%s", unneeded, actual);
    printf("unneeded: %s\n", unneeded);
    printf("actual: %s\n", actual);
  }

  return 0;
}

编译代码的输出:

unneeded: Code:
actual: HARK
unneeded: Name:
actual: Oscar
unneeded: MRTE:
actual: Train