【问题标题】:Is there a way to compare every line in one text file to one line in another text file in C?有没有办法将一个文本文件中的每一行与 C 中另一个文本文件中的一行进行比较?
【发布时间】:2018-10-20 19:44:21
【问题描述】:

例如,我有一个包含 400 多个英文单词的索引文本文件,然后我有另一个文本文件,每行都有解密的文本。

我想用我的解密文本文件的每一行检查索引文件中的每个英文单词(因此检查 400 多个英文单词是否匹配每行解密文本)

我正在考虑使用strncmp(decryptedString, indexString, 10),因为我知道如果下一个字符是NULL,strncmp 就会终止。

我的解密文本文件的每一行有 352 个字符长,其中存储了大约 4000 万行文本(每一行来自不同的输出)。

这是解密一个公平密码;我知道我的解密算法有效,因为我的教授给了我们一个例子来测试我们的程序,它运行良好。

我已经连续六天在这个项目上工作,这是我唯一坚持的部分。我根本无法让它工作。我试过使用

while(getline(&line, &len, decryptedFile) != -1){
    while(getline(&line2, &len2, indexFile) != -1){
        if(strncmp(decryptedString, indexString, 10) == 0){
            fprintf(potentialKey, "%s", key); 
        }
    }
}

但我从来没有得到任何匹配。我尝试将每个字符串存储到数组中并一次测试一个字符,但这对我也不起作用,因为它会列出所有英文单词都在一行上。我只是迷路了,所以任何正确方向的帮助或指示将不胜感激。提前谢谢你。

编辑:根据 Clifford 在 cmets 的建议,这是我正在尝试做的一个示例

假设 indexFile 包含:

HELLO
WORLD
PROGRAMMING
ENGLISH

并且解密后的文件包含

HEVWIABAKABWHWHVWC
HELLOHEGWVAHSBAKAP
DHVSHSBAJANAVSJSBF
WORLDHEEHHESBVWJWU
PROGRAMMINGENGLISH

我正在尝试将 indexFile 中的每个单词与 decryptedFile 进行比较,一次一个。因此 indexFile 中的所有四个单词都将分别与第 1 行、第 2 行、第 3 行、第 4 行和第 5 行进行比较。

【问题讨论】:

  • 你考虑过使用 memcmp(const void *str1, const void *str2, size_t n)) 吗?我不明白你为什么只比较 10 个字节
  • 考虑strstr() 是否可以提供帮助。还要说明是否需要在ordinary中找到din
  • 我只比较 10 个字节,因为解密后的文本只包含英文单词,所以如果前 10 个字节不匹配,那么我知道这是错误的解密文本,我会移动到下一行。
  • 在我的情况下,strstr() 的问题在于它每次都是匹配的,因为如果解密文本,每行中都会找到一个索引中的单词,所以它不会使我的列表更小
  • 编辑:乔纳森,你的评论给了我一个想法,我想听听你的意见。如果我删除索引文件中所有

标签: c file-comparison


【解决方案1】:

如果您要做的是检查输入行是否以单词开头,您应该使用:

strncmp(line, word, strlen(word));

如果你知道lineword长,你可以使用

memcmp(line, word, strlen(word));

如果您使用相同的单词重复执行此操作,最好将word 的长度保存在与word 本身相同的数据结构中,以避免每次都重新计算它。

这是strncmp 的常见用例。请注意,您对strncmp 的描述有些不准确。当它在任一参数中遇到 NUL 时它将停止,但仅当两个参数在同一位置都有 NUL 或计数用尽而没有遇到差异时,它才会返回 equal。

strncmplineword 长这一事实更安全,因为memcmpstrncmp 之间的速度差异非常小。

但是,有这么多数据和这么多字要检查,您应该尝试一些可以减少您需要进行的比较次数的方法。例如,您可以将单词放入 Trie 中。或者,如果这看起来工作量太大,您至少可以按它们的第一个字母对它们进行分类,并且只使用第一个字母与该行的第一个字母匹配的那些(如果有的话)。

如果您要在行中的任何位置查找单词的实例,那么您将需要更复杂的搜索策略。这个问题有很多算法; Aho-Corasick 既有效又简单,尽管有更快的方法。

【讨论】:

  • 你说得对; line 肯定比 word 长,所以我会尝试 strlen(word) for size_t。这么简单的事情,却完全不在我的脑海里。谢谢,这绝对为我指明了正确的方向!
【解决方案2】:

如果一行解密文本的长度为 352 个字符,并且索引中的每个单词都不长 352 个字符,那么一行解密文本将永远不会匹配索引中的任何单词。

从这里我认为你误解了要求,并根据误解提出了一个问题。

具体来说,我怀疑您希望将解密行(而不是整行)中的每个单词与索引中的每个单词进行比较,以确定解密行中的所有单词是否都可以接受。为此,第一步是将解密的字符行分解为单个单词-例如也许在解密的文本中找到分隔单词(空格、制表符、逗号?)的字符并将它们替换为零终止符(这样您就可以使用 strcmp() 并且不必担心“foobar”与“foo”不正确匹配" 只是因为第一个字母匹配)。

请注意,可能存在潜在的优化。例如。如果您知道解密文本中的一个单词是 8 个字符(您必须知道将零终止符放在正确的位置)并且如果您的索引被拆分为“每个单词长度的一个列表”(例如具有 3 个字符的索引词列表、具有 4 个字符的索引词列表等),那么您可能可以跳过很多字符串比较(并且仅将解密行中的单词与具有相同长度的单词进行比较)指数)。在这种情况下(您知道两个单词的长度已经相同),您还可以避免修改原来的 352 个字符(您不需要在每个单词后插入零终止符)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-09
    • 2015-06-22
    • 1970-01-01
    • 2016-12-10
    • 2012-09-25
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    相关资源
    最近更新 更多