如何从txt文件中读取制表符分隔的字符串并将它们放入变量中?

时间:2012-06-06 05:35:49

标签: c file

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

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

所以,它看起来像是让第一个数字正常(作为一个字符串)并将其放入变量,看到标签,并抓住标签后的第一个序列,并在将其放入另一个变量后停在那里。我如何纠正这种情况?

2 个答案:

答案 0 :(得分:5)

您可以尝试更改sscanf

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

%s说明符在遇到空白时停止。这就是为什么它只读取 study 而不是研究基于堆的优先级队列%[^\n]告诉它:“读到换行符”。另一个问题:您应该测试sscanf返回的值,以确保它填充了所需数量的对象。


您还可以将第一个整数读作整数,将position更改为int并使用%d代替%s

修改

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

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

答案 1 :(得分:3)

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

以下是代码:

#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,然后读取记录的所有剩余字符(TAB,空格,NEWLINE以外的所有字符),直到NEWLINE为string3。

在我的真实程序中,我正在对string1和string2进行特定处理。我的输出是与string3一起处理的结果。换句话说,我的输出也是TAB分隔的,string3的原始内容没有改变。

如果您有一个包含三个或更多字段的TAB分隔文件,则以下(在Linux上)应该为真:

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

希望这有助于其他人处理TAB分隔文件。