基于字符串比较的单词翻译程序无法正常工作

时间:2015-06-11 14:43:00

标签: c arrays string

我制作了一个程序,从文件english_dictionary.txt读取英语中最常用的100个单词,并在foreign_dictionary.txt中将各个单词的翻译用外语翻译。

.txt个文件的内容放在两个char *array [100]

然后程序从文件text_to_translate.txt读取,其中包含英文文本,如果找到匹配项,将用外语替换英文字符串(单词)。但它不起作用,有人可以告诉我为什么?

以下是我的代码:

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

int main(void){

    char *foreign[100];
    int i;

    FILE *fp = fopen("foreign_dictionary.txt", "r");

    for (i = 0; i < 100; ++i){
        foreign[i] = malloc(15 * sizeof(char));
        fgets(foreign[i], 20, fp);
    }
    fclose(fp);

    char *english[100];

    fp = fopen("english_dictionary.txt", "r");

    for (i = 0; i < 100; ++i){
        english[i] = malloc(15 * sizeof(char));
        fgets(english[i], 20, fp);
    }
    fclose(fp);
//------------------------if find a match and print the translation--------
    char *buffer = malloc(15 * sizeof(char));
    int flag = 0;
    fp = fopen("text_to_translate.txt", "r");
    while (fgets(buffer, 20, fp) != NULL){
        for (i = 0; i < 100; ++i)
            if (english[i] == buffer){
                printf("%s", foreign[i]);
                flag = 1;
            }
        if (flag == 1)
            continue;
        else
            printf("%s", buffer);
    }

    return 0;
}

P.S。如果需要,字典文件是这样的:

the
and
to
of
.
.
.

3 个答案:

答案 0 :(得分:5)

  • 首先在您的代码中,您正在做

    english[i] == buffer
    

    比较字符串,但无法使用==运算符比较字符串。您需要改为使用strcmp()

  • 第二次fgets()读取并存储尾随newline。最好手动剥离它们,大多数情况下它们会导致 string 比较失败。

  • 最后您将15个字节分配给您fgets()提供给fgets()的缓冲区,同时char的最大读取限制为sizeof(char) 1}}是19(比提供的少1)。如果输入超过14 1 s,则可以通过缓冲区溢出来创建undefined behaviour。此外,C保证在fgets()中生成NULL。你可以放弃那部分。

建议:关于这个程序的设计,我觉得还有一个bug。您永远不会检查fgets()是否成功,只是无条件地读取文件100次,然后使用这些值。这可能会产生两个问题。

  1. 部分内容可以有效地成为fgets()。因此,稍后在使用这些值时,您将再次面对UB。
  2. 如果您使用固定大小(IMHO)循环固定次数的迭代,则没有要求来使用动态内存分配。
  3. 稍微改变一下你的方法,比如

    • 创建一个足够长的临时缓冲区数组。
    • 使用NULL
    • 读取该临时数组的输入
    • 检查NULL成功(非newline返回值)

      • 如果不是NULL

        • 删除最后 Bind(Of IDbConnection).ToMethod(Function(context) New OracleConnection(ConnectionStringFactory.GetConnection(DBC.ConnectionStrings.Oracle))).WhenInjectedInto(Of AccountBalancesLookup)() Bind(Of IDbConnection).ToMethod(Function(context) New OracleConnection(ConnectionStringFactory.GetConnection(DBC.ConnectionStrings.Oracle))).WhenInjectedInto(Of MFUtility)()
        • 的输入
        • 计算保持字符串所需的长度
        • 将动态内存分配给指针数组
        • 复制输入
      • if Bind(Of IDbConnection).ToMethod(Function(context) New OracleConnection(ConnectionStringFactory.GetConnection(DBC.ConnectionStrings.Oracle))).WhenInjectedInto(Of AccountBalancesLookup, MFUtility)()

        • 它指的是文件结尾,没有什么可读的了,所以你可以走出循环来读取该特定文件的输入。

答案 1 :(得分:1)

if (english[i] == buffer)不是比较字符串的方法。

查看strcmp()

您应该编写如下代码:

if (strcmp(english[i], buffer) == 0)

答案 2 :(得分:1)

让我们仔细看看吧!这english[i] == buffer做了什么?

如您所知,buffer的类型是指向char的指针。所有指针都只是一个地址。地址是数字类型。例如,0xff432354指向由此数字索引的内存位置。因此,当您编写buffer == foo时,计算机实际上会比较地址编号本身而不是其内容。

在您的情况下,您应该比较他们的内容而不是他们的地址。因此,函数strcmp会为您执行此操作。