繁体   English   中英

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

[英]Reading data from a text file in C?

因此,我在使用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);
}

我需要填写空白。

任何帮助将不胜感激!

您可以按如下方式调用。例如,我放置了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;
}

我认为读取文件中格式化字符串的最佳方法是使用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;
}

试试这个代码

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;
}

如果我正在做您正在做的事情,那么我会那样做:)

我看到很多人因推荐人们使用scanf()strtok()之类的功能而感到愤慨(不是在这里,我一般意思是说SO),尽管事实上这些功能被统一认为是邪恶的 ,不仅仅是因为它们不是线程安全的,但是因为它们以难以预测的方式修改了参数,并且调试起来非常痛苦。

如果您要malloc()ing用于读取文件的输入缓冲区,请始终使其至少为4kB-这是内核仍然可以为您提供的最小页面,因此,除非您要进行不那么笨拙的100字节小分配malloc() ,您也可能会这样,并且不要害怕分配10倍或100倍的价格,如果这样可以使生活变得轻松。

因此,对于您正在处理输入数据的少量文本文件的此类问题,您可以执行以下操作:

  • malloc()自己是一个很好的大缓冲区,足够大,足以容纳整个桶中的净空
  • 打开文件,使用read()将整个该死的东西吞噬掉,然后关闭它
  • 记录您在n_chars读取了多少字节(或其他内容)
  • 一次通过缓冲区,然后1)用NUL替换所有换行符,然后2)将每行的开始(在换行符之后!)记录到lines数组中的连续位置中(例如char **lines; lines=malloc(n_chars*sizeof(char *)) :行数不能超过字节!)
  • (可选)进行时,前进行开始指针以跳过前导空格
  • (可选)使用时,使用NUL覆盖尾随空白
  • 保持行数并保存在n_lines
  • 完成操作后,请记住free()该缓冲区

现在,你有什么? 您有一个字符串数组,它们是文件的行(可选,每行前导空格和尾随空格都被去除),并且您可以使用它来做自己喜欢的事情。

所以你会怎么做?

像这样一步一步地遍历所有行:

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

}

你也许忽略空行和一些由“#”开始。 您的配置文件现在有注释!

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

    len = strlen("insert");
    if( 0== strncmp(lines[i], "insert", len) ) {
        n = strtol(lines[i]+len+1, &endp, 10);
        // error checking
        tree_insert( (int)n );
        continue;
    }

    len = strlen("delete");
    if( 0== strncmp(lines[i], "delete", len) ) {
        n = strtol(lines[i]+len+1, &endp, 10);
        // error checking
        tree_delete( (int)n );
    }
}

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

还有其他想法吗? 把自己打昏!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM