3

我有一个文件,我正在尝试读取和填充变量。该文件由以下内容组成:

0\ttake a nap\n
1\tstudy heap-based priority queue\n
101\treview trees for Midterm 2\n
3\tdo assignment 7\n

这可能很难阅读,但是您可以看到有一个整数开头,然后是一个制表符,然后是一个字符串,然后是一个换行符。我需要取整数并将其放入变量中,检测制表符,并将制表符后面的字符串放入变量中,检测换行符,获取两个变量并使用信息创建一个节点,然后重新开始下一行。经过数小时的互联网搜索,这就是我想出的:

char activity[SIZE];
 char position[SIZE];
 char line[100];

  FILE *infile;
  char *inname = "todo.txt";

  int i = 0;


  infile = fopen(inname, "r");
  if (!infile) {
    printf("Couldn't open %s for reading\n");
    return 0;
  }
while(i < 100 && fgets(line, sizeof(line), infile) != NULL){
        sscanf(line, "%s\t%s", position, activity);
        printf("%s\n", position);
        printf("%s\n", activity);
        i++;
    }

在上面的 txt 文件上运行此测试代码时,我得到以下结果:

0
take
1
study
101
review
3
do

因此,在我看来,它正在获取第一个数字(作为字符串)并将其放入变量中,查看选项卡,并在选项卡之后抓取第一个序列并在将其放入另一个变量后停在那里。我该如何纠正这种情况?

4

2 回答 2

5

您可以尝试更改sscanf

sscanf(line, "%s\t%[^\n]", position, activity);

说明%s符在遇到空白时停止。这就是为什么它只读取study而不是study-based priority queue的原因。告诉它: “%[^\n]读到换行符”。另一个问题:您应该测试返回的值sscanf以确保它填充了所需数量的对象。


您还可以将第一个整数读取为整数,更改positionint并使用%d而不是%s.

编辑

为了让自己清楚,我的建议是:

int position;
sscanf(line, "%d\t%[^\n]", &position, activity);
于 2012-06-06T05:39:49.873 回答
4

以下对我的用例非常有效。我想将制表符分隔文件的前两个字段读入字符串变量,然后将每行的其余部分读入最终字符串变量。

这是代码:

#include <stdlib.h>
#include <stdio.h>

int main()
{
   unsigned char     string1 [255];
   unsigned char     string2 [255];
   unsigned char     string3 [255];

   /* read from stdin until done */
   while(!feof(stdin))
   {
      fscanf( stdin, "%[^\t]\t%[^\t]\t%[^\n]\n", string1, string2, string3 );
      printf( "%s\t%s\t%s\n",                    string1, string2, string3 );
   }

   return(0);
}

我正在阅读 STDIN,因为我使用该程序创建了一个命令行过滤器。

fscanf 代码说明:

%[^\t] - any character that is not a TAB
\t     - the TAB character
%[^\n] - any character that is not a NEWLINE
\n     - the NEWLINE character

因此,我的 fscanf 正在读取直到第一个 TAB 的所有字符(包括空格但不包括 TAB 本身)并将字符串放入 var string1,直到第二个 TAB 的所有字符(包括空格但不包括 TAB 本身)并放置字符串到 var string2 中,然后将记录的所有剩余字符(制表符、空格、除 NEWLINE 之外的所有字符)读取到 NEWLINE 到 string3 中。

在我的真实程序中,我对string1和string2进行了特定的处理。我的输出是与 string3 一起处理的结果。换句话说,我的输出也是以制表符分隔的,而 string3 的原始内容保持不变。

如果您有一个包含三个或更多字段的制表符分隔文件,那么以下(在 Linux 上)应该是正确的:

cat FILE | ABOVE_PROGRAM > OUT_FILE
diff FILE OUT_FILE       # This should yield nothing (no differences)

希望这将有助于其他人处理制表符分隔的文件。

于 2013-11-05T16:06:18.313 回答