繁体   English   中英

从C中的文本文件读取

[英]Reading from Text files in C

确实是一个小问题。 最好读取一个包含X个单词的文本文件,并将每个单词一个接一个地添加到链接列表中。 即青蛙是老。

因此,The,Frog,Is和Old将分别放入一个ListNode中,所有这些都是从文件中读取的。

真的想知道与fscanf一起使用的最佳功能,如果fscanf甚至是最佳选择。 所有建议都很棒!

干杯。

编辑:我的查询是真的,如果我想解析一个大的文本文件,是否最好将一个单词fscanf逐个地放入数组,添加到列表,自由数组,然后重复? 还是有更有效的方法

“%s”转换说明符将匹配非空格字符。

#define QUOTE(s) #s
#define STR(s) QUOTE(s)

#ifndef BUFSIZE
#  define BUFSIZE 255
#endif

char buf[BUFSIZE+1];
while (fscanf(fin, "%" STR(BUFSIZE) "s", buf)) {
    /* buf holds next word. Todo:
       + allocate space for word
       + copy word to newly allocated space
       + add to linked list
     */
}

另外, strtok可用于使用指定的一组字符(作为字符数组)将字符串标记化(分解)为子字符串。 您的系统可能还具有strsep ,旨在取代strtok strtokstrsep修改您传入的数组,因此请注意,这不会导致访问数据的代码其他部分出现问题。 strsep不是线程安全的; 如果您有多个线程访问要解析的字符串,请使用strsepstrtok_r

#ifndef BUFSIZE
#  define BUFSIZE 256
#endif

const char separators[] = "\t\n\v\r\f !\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~";
char buf[BUFSIZE], *line, *word, *rest;

while (fgets(buf, BUFSIZE+1, fin)) {
    rest = line = buf;
    while ((word = strtok_r(line, separators, &rest))) {
        /* Todo:
           + allocate space for word
           + copy word to newly allocated space
           + add to linked list
        */
        line=rest;
    }
}

由于第二个示例一次从文件中读取一行以供strtok_r处理,因此如果文件中的任何一行的长度超过BUFSIZE-1 字符,并且一行中的BUFSIZE-1 st和BUFSIZE th字符均为字母,则第二个示例将单词分成两部分。 一种解决方案是创建一个缓冲的字符串流,以便在到达缓冲区的末尾时,缓冲区中剩余的所有内容都移到最前面,而缓冲区的其余部分则充满了文件中的更多数据(只是请注意字长比缓冲区长;在生产代码中,这是一个潜在的安全漏洞,可能导致拒绝服务攻击。

上述所有功能的问题是它们不能处理输入中的空字符。 如果您想解析可能包含空字符的数据,则需要使用非标准函数,其中包括编写自己的函数。

至于效率,您使用的任何算法都需要从文件中读取(复杂度为O(n),并且需要I / O,从而降低程序速度)并分配内存来存储字。 无论您使用fscanfstrtok还是其他方法,时间和空间的复杂性变化都不大。 关于唯一可能的事情是分配了多少个中间缓冲区。 找到最有效的实施方案的最佳选择是尝试一对夫妇并进行介绍。

除非您拥有“效率不够的方法”,否则您不应该在寻找“更有效的方法”。

但是类似strtok东西可能不需要大量malloc可以满足您的需求。 它使您可以将琴弦切成适当的位置 (请谨慎使用!)

如果您追求高速,请在现代台式计算机上...您可以使用多线程。

  • 一个线程填充字符缓冲区(例如4Ko),并且仅执行此操作
  • 一个线程读取缓冲区,解析单词并将其添加到列表中
  • 如果您不需要整个列表,则一个线程可以执行您在列表上所做的任何操作

这个想法是等待I / O时进程不会休眠。 如果您有很多CPU内核,则要提高速度,就是将文件切成大块,然后一个内核处理一个块。 复杂代码和错误的机会很多,但是,速度并不便宜...

暂无
暂无

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

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