【问题标题】:getting string from file without punctuation for spell checking outputting with original punctuation.从文件中获取不带标点符号的字符串,以使用原始标点符号进行拼写检查。
【发布时间】:2012-04-04 18:32:08
【问题描述】:

您好,我正在用 c 语言制作一个拼写检查器,它在字符串数组中有一个字典,并使用二进制搜索在字典中查找单词。

我的问题是我正在尝试从文件中读取文本并将文本输出回新文件,其中错误的单词突出显示如下:** 拼写错误 ** 但该文件将包含诸如 .,!?它应该输出到新文件,但在将单词与字典进行比较时显然不存在。

所以我想要这个:

text file: "worng!"

new file: "** worng **!"

我一直在尽我所能解决这个问题,并且在谷歌上花了很长时间,但还没有接近解决方案。到目前为止,我已经编写了以下代码来读取每个字符并填充两个 char 数组一个小写临时用于字典比较,一个输入用于原始单词,如果没有标点符号则可以使用,但显然当标点符号存在时我会以这种方式释放空间我'确定有更好的方法可以做到这一点,但我找不到它,所以任何指针都会受到赞赏。

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

#define MAX_STRING_SIZE 29  /*define longest non-technical word in english dictionary plus 1*/

/*function prototypes*/
int dictWordCount(FILE *ptrF);  /*counts and returns number of words in dictionary*/
void loadDictionary(char ***pArray1, FILE *ptrFile, int counter);   /*create dictionary array from file based on word count*/
void printDictionary(char **pArray2, int size); /*prints the words in the dictionary*/
int binarySearch(char **pArray3, int low, int high, char *value);   /*recursive binary search on char array*/

void main(int argc, char *argv[]){
    int i;  /*index*/
    FILE *pFile;    /*pointer to dictionary file*/
    FILE *pInFile;  /*pointer to text input file*/
    FILE *pOutFile; /*pointer to text output file*/
    char **dict;    /*pointer to array of char pointer - dictionary*/
    int count;      /*number of words in dictionary*/
    int dictElement;    /*element the word has been found at returns -1 if word not found*/

    char input[MAX_STRING_SIZE];    /*input to find in dictionary*/
    char temp[MAX_STRING_SIZE];
    char ch;    /*store each char as read - checking for punctuation or space*/
    int numChar = 0; /*number of char in input string*/

    /*************************************************************************************************/
    /*open dictionary file*/
    pFile = fopen("dictionary.txt", "r");   /*open file dictionary.txt for reading*/
    if(pFile==NULL){    /*if file can't be opened*/
        printf("ERROR: File could not be opened!/n");
        exit(EXIT_FAILURE);
    }

    count = dictWordCount(pFile);
    printf("Number of words is: %d\n", count);

    /*Load Dictionary into array*/
    loadDictionary(&dict, pFile, count);

    /*print dictionary*/
    //printDictionary(dict, count);
    /*************************************************************************************************/
    /*open input file for reading*/
    pInFile = fopen(argv[1], "r");
    if(pInFile==NULL){  /*if file can't be opened*/
        printf("ERROR: File %s could not be opened!/n", argv[1]);
        exit(EXIT_FAILURE);
    }
    /*open output file for writing*/
    pOutFile = fopen(argv[2], "w");
    if(pOutFile==NULL){ /*if file can't be opened*/
        printf("ERROR: File could not be created!/n");
        exit(EXIT_FAILURE);
    }

    do{
        ch = fgetc(pInFile);                /*read char fom file*/

        if(isalpha((unsigned char)ch)){     /*if char is alphabetical char*/
            //printf("char is: %c\n", ch);
            input[numChar] = ch;            /*put char into input array*/
            temp[numChar] = tolower(ch);    /*put char in temp in lowercase for dictionary check*/
            numChar++;                      /*increment char array element counter*/
        }
        else{
            if(numChar != 0){
                input[numChar] = '\0';  /*add end of string char*/
                temp[numChar] = '\0';

                dictElement = binarySearch(dict,0,count-1,temp);    /*check if word is in dictionary*/

                if(dictElement == -1){  /*word not in dictionary*/
                    fprintf(pOutFile,"**%s**%c", input, ch);
                }
                else{   /*word is in dictionary*/
                    fprintf(pOutFile, "%s%c", input, ch);
                }
                numChar = 0;    /*reset numChar for next word*/
            }
        }
    }while(ch != EOF);

    /*******************************************************************************************/
    /*free allocated memory*/
    for(i=0;i<count;i++){
        free(dict[i]);
    }
    free(dict);

    /*close files*/
    fclose(pInFile);
    fclose(pOutFile);

}

【问题讨论】:

  • 不太确定为什么这被否决了我在这上面花了 2 天时间并尝试了不同的方法,但我确实被卡住了。我还在包括这个网站在内的多个网站上搜索了一个解决方案,而我现在拥有的代码就是我能够通过我的研究完成的。我想提醒人们,我是一名学生,并且只学习了大约 9 周的 c,因此向更有经验的人寻求指导是很自然的。

标签: c string


【解决方案1】:

我不能 100% 确定我是否正确理解了您的问题,但我会试一试。

首先,你的循环

do{
    ch = fgetc(pInFile);
    /* do stuff */
}while(ch != EOF);

也会在到达文件末尾时运行,因此如果文件的最后一个字节是按字母顺序排列的,您将打印一个不需要的 EOF 字节到输出文件,或者,因为您将 ch 转换为unsigned char 将其传递给 isalpha() 时,通常会产生 255 [对于EOF = -1 和 8 位 unsigned char],它会在某些语言环境(例如 en_US.iso885915)中被视为字母字符,从而导致在抑制输入文件的最后一个单词。

为了解决这个问题,首先,在将ch传递给isalpha()时不要强制转换,其次在循环中添加一些逻辑以防止无意处理EOF。如果需要,我选择用换行符替换它,因为这很简单。

然后剩下的就是打印出不紧跟字母字符的非字母字符:

do{
    ch = fgetc(pInFile);                /*read char fom file*/

    if(isalpha(ch)){                    /*if char is alphabetical char*/
        //printf("char is: %c\n", ch);
        input[numChar] = ch;            /*put char into input array*/
        temp[numChar] = tolower(ch);    /*put char in temp in lowercase for dictionary check*/
        numChar++;                      /*increment char array element counter*/
    }
    else{
        if(numChar != 0){
            input[numChar] = '\0';  /*add end of string char*/
            temp[numChar] = '\0';

            dictElement = binarySearch(dict,0,count-1,temp);    /*check if word is in dictionary*/

            if(dictElement == -1){  /*word not in dictionary*/
                fprintf(pOutFile,"**%s**%c", input, (ch == EOF) ? '\n' : ch);
            }
            else{   /*word is in dictionary*/
                fprintf(pOutFile, "%s%c", input, (ch == EOF) ? '\n' : ch);
            }
            numChar = 0;    /*reset numChar for next word*/
        }
        else
        {
            if (ch != EOF) {
                fprintf(pOutFile, "%c",ch);
            }
        }
    }
}while(ch != EOF);

【讨论】:

  • 谢谢!!这正是我想要做的,但我就是不知道怎么做。至于强制转换 ch 是我从其他示例中得到的,但我想我并没有真正正确地研究它的原因。
  • 一般情况下,不需要转换fgetcgetchar 的结果。像isalpha 这样的函数采用int 参数,该参数必须是EOFunsigned char 的值,你从fgetc 得到什么,所以不需要强制转换,如果结果是@987654339 @,可能有害。对于无法处理 EOF 的函数,您必须在调用之前进行检查,然后强制转换不会造成伤害(如果函数将 unsiged char 作为参数,可能需要避免编译器警告) .经验法则:除非您知道有必要或编译器告诉您,否则不要强制转换。
【解决方案2】:

现在看起来,如果 char 不是按字母顺序排列的,它会触发 if(isalpha((unsigned char)ch)){else 块,并且字符本身会被忽略。

如果您添加一条语句以将所有非字母字符完全按照输入的方式打印出来,我认为这会达到您想要的效果。这需要进入 else 块内部和 if(numChar != 0){ 块之后,并且只是一个简单的 fprintf 语句。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    相关资源
    最近更新 更多