从C中的文本文件中读取数据?

时间:2014-03-14 04:14:28

标签: c fopen strtok

所以我很擅长从C中的文本文件中读取数据。我习惯使用scanf或硬编码来获取输入。

我正在尝试学习如何不仅从文本文件中读取数据而且还要操纵该数据。例如,假设一个名为bst.txt的文本文件具有以下用于在二叉搜索树上执行操作的信息:

insert 10
insert 13
insert 5
insert 7
insert 20
delete 5
delete 10
....

通过这个例子,我将得到以下代码:

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

int main()
{ 
  FILE *fptr;
  char *charptr;
  char temp[50];

  fptr = fopen("bst.txt", "r");

  while(fgets(temp, 50, fptr) != NULL)
  {
    charptr = strtok(temp, " ");

    while(charptr != NULL)
    {
      charptr = strtok(NULL, " ");
    }
  }

return 0;
}

我知道在第一个while循环中strtok()拆分文本文件中的每一行,并且在第二个while循环中strtok()在程序识别空格时分离,在这种情况下会将操作与整数分开

所以我的主要问题是,例如,在单词“insert”与整数“10”分开之后,我如何让程序继续这样:

if(_____ == "insert")
{
  //read integer from input file and call insert function, i.e. insert(10);
}

我需要填空。

任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:0)

你可以按如下方式打电话。例如我已经放了printf但你可以替换你的insert/delete功能。

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

int main()
{ 
  FILE *fptr;
  char *charptr;
  char temp[50];

  fptr = fopen("bst.txt", "r");

  while(fgets(temp, 50, fptr) != NULL)
  {
    charptr = strtok(temp, " ");

    if(strcmp(charptr,"insert")==0)
    {
      charptr = strtok(NULL, " ");

      printf("insert num %d\n",atoi(charptr));
    }
    else if(strcmp(charptr,"delete")==0)
    {
      charptr = strtok(NULL, " ");

      printf("delete num %d\n",atoi(charptr));
    }
  }

return 0;
}

答案 1 :(得分:0)

我认为在文件中读取格式化字符串的最佳方法是使用fscanf,以下示例说明如何解析文件。您可以存储charptrvalue以进行进一步操作:

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

int main()
{ 
  FILE *fptr;
  char charptr[50];
  int value;

  fptr = fopen("bst.txt", "r");

  while (fscanf(fptr, "%s%d", charptr, &value) > 0)
  {
      printf("%s: %d\n", charptr, value);
  }

  return 0;
}

答案 2 :(得分:0)

试试这段代码

int main(){
FILE *fp;
char character[50];
int value;
fptr = fopen("input.txt", "r");

while (fscanf(fp, "%s%d", character, &value) > 0)
{
  if(strcmp(character,"insert")==0){
      insert(value);//call you function which you want value is 10 or change according to file
  }
}
return 0;
}

答案 3 :(得分:0)

如果我正在做你正在做的事情,我会这样做:)

我看到很多人被推荐(不是在这里,我的意思是在一般情况下)推荐人们使用像scanf()strtok()这样的功能,尽管这些功能被统一考虑邪恶,不仅仅是因为他们不是线程安全的,而是因为他们以难以预测的方式修改他们的论点,并且是调试屁股的巨大痛苦。

如果你是malloc()ing用于从文件中读取的输入缓冲区,总是使其至少达到4kB - 这是内核可以给你的最小页面无论如何,所以除非你做了一个非常愚蠢的小100字节malloc(),否则你也可以 - 并且不要害怕分配10x或100x那个如果这让生活变得轻松。

因此,对于您处理输入数据的小文本文件的这类问题,请按以下步骤操作:

  • malloc()你自己是一个很好的大缓冲区,足以在整个文件中用水桶和余量的空间啜饮
  • 打开文件,用read()啜饮整个该死的东西,并关闭它
  • 记录您在n_chars(或其他)
  • 中读取的字节数
  • 执行一次通过缓冲区并1)用NUL替换所有换行符,2)将每行的开头(在换行符之后!)记录到lines数组中的连续位置(例如{{1 }}:行不能超过字节!)
  • (可选)当你开始时,提前你的行首指针跳过前导空格
  • (可选)随你用NUL覆盖尾随空格
  • 随时保留行数并将其保存在char **lines; lines=malloc(n_chars*sizeof(char *))
  • 当你完成它时,请记住n_lines缓冲区

现在,你有什么?你有一个字符串数组,这些字符串就是你文件的行(可选择每行删除前导和尾随空格),你可以用它来做你想做的事情。

那你做什么?

逐行浏览行数组,如下所示:

free()

已经你忽略了以&#34;#&#34;开头的空行和行。您的配置文件现在有评论!

for(i=0; i<n_lines; i++) {
    if( '\0'==*lines[i] || '#' == *lines[i] )
        continue;
    // More code

}

现在,您可能会看到10种方法可以使这些代码更好。我也是。包含关键字和指向适当树函数的函数指针的结构怎么样?

其他想法?自己敲门!