循环未运行

时间:2018-01-06 03:52:52

标签: c

我尝试将文件中的文字与用户输入进行比较 一切都完成但是第二循环还没有运行?有可能检查吗?

基本上我要做的就是:就像有一句话'我的'在我的text.file中。现在我想通过比较这个text.txt文件' my'来表明它是一个代名词。用户输入'我的'在他的判决中。

Test.txt文件:

  

我们
  我
  我
  你

尝试将test.txt文件的字符串与代码1进行比较。

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

#define FNAME "test.txt"    /* if you need constants, define them */
#define NOUN "nouns.txt"
#define VERB "verbs.txt"
#define TENC   10
#define MAXC  100

int main (void) {

    int c = 0, i = 0, ndx = 0,          /* misc. counters & index    */
        fwords = 0,                     /* number of words in file   */
        uwords = 0;                     /* number of words from user */
    char arr[MAXC] = "",                /* storage for file contents */
        str1[MAXC] = "",                /* storage for user string   */
        wordsfile[TENC][TENC] = { "" }, /* separated words from file */
        wordsnoun[TENC][TENC] = { "" },
        wordsverb[TENC][TENC] = { "" },
        wordsuser[TENC][TENC] = { "" }; /* separated words from user */

        //wordsnoun[] = { "dog", "fleas" };  /* nouns - example       */

    size_t len = 0,                     /* string length             */
        nnouns = sizeof wordsnoun / sizeof *wordsnoun,
        nverbs = sizeof wordsverb / sizeof *wordsverb;  /* no. nouns */


    FILE *fp = fopen (FNAME, "r");

    if (fp == NULL) {       /* validate file open for reading */
        perror (FNAME);
        return 1;
    }

    printf ("\n Reading from '%s' and separating into words by line :\n"
            " --------------------------------------------------------\n\n",
            FNAME);

    /* read characters from file into 'arr' and separate into words
     * by newline into 'wordsfile'. nul-terminate each word. protect
     * all array bounds and against non-POSIX eof.
     */
    while (ndx < MAXC && fwords < TENC && (c = fgetc(fp)) != EOF) {
        if (c == '\n') {    /* separate words in file by line */
            wordsfile[fwords++][i] = 0;    /* nul-terminate */
            i = 0;          /* reset words character count */
        }
        else  /* assign char to both wordsfile & arr */
            wordsfile[fwords][i++] = arr[ndx++] = c;

        if (i >= TENC) {    /* protect array bounds */
            fprintf (stderr, "error: wordsfile - word too long.\n");
            return 1;
        }
    }
    if (i)  /* handle non-POSIX file ending (no '\n') */
        wordsfile[fwords++][i] = 0;  /* nul-terminate */

    fclose (fp);    /* close the file - done with it */


    FILE *np = fopen (NOUN, "r");

    if (np == NULL) {       /* validate file open for reading */
        perror (NOUN);
        return 1;
    }

    printf ("\n Reading from '%s' and separating into words by line :\n"
            " --------------------------------------------------------\n\n",
            NOUN);

    /* read characters from file into 'arr' and separate into words
     * by newline into 'wordsfile'. nul-terminate each word. protect
     * all array bounds and against non-POSIX eof.
     */
    while (ndx < MAXC && fwords < TENC && (c = fgetc(fp)) != EOF) {
        if (c == '\n') {    /* separate words in file by line */
            wordsnoun[fwords++][i] = 0;    /* nul-terminate */
            i = 0;          /* reset words character count */
        }
        else  /* assign char to both wordsfile & arr */
            wordsnoun[fwords][i++] = arr[ndx++] = c;

        if (i >= TENC) {    /* protect array bounds */
            fprintf (stderr, "error: wordsnoun - word too long.\n");
            return 1;
        }
    }
    if (i)  /* handle non-POSIX file ending (no '\n') */
        wordsnoun[fwords++][i] = 0;  /* nul-terminate */

    fclose (np);    /* close the file - done with it */




    FILE *vp = fopen (VERB, "r");

    if (vp == NULL) {       /* validate file open for reading */
        perror (VERB);
        return 1;
    }

    printf ("\n Reading from '%s' and separating into words by line :\n"
            " --------------------------------------------------------\n\n",
            VERB);

    /* read characters from file into 'arr' and separate into words
     * by newline into 'wordsfile'. nul-terminate each word. protect
     * all array bounds and against non-POSIX eof.
     */
    while (ndx < MAXC && fwords < TENC && (c = fgetc(fp)) != EOF) {
        if (c == '\n') {    /* separate words in file by line */
            wordsverb[fwords++][i] = 0;    /* nul-terminate */
            i = 0;          /* reset words character count */
        }
        else  /* assign char to both wordsfile & arr */
            wordsverb[fwords][i++] = arr[ndx++] = c;

        if (i >= TENC) {    /* protect array bounds */
            fprintf (stderr, "error: wordsverb - word too long.\n");
            return 1;
        }
    }
    if (i)  /* handle non-POSIX file ending (no '\n') */
        wordsverb[fwords++][i] = 0;  /* nul-terminate */

    fclose (vp);    /* close the file - done with it */




    for (i = 0; i < fwords; i++) /* output words from file */
        printf ("wordsfile[%d] : %s\n", i, wordsnoun[i]);

    printf ("\n Split string by space into words :\n"
            " --------------------------------------\n"
            " Input  a string : ");    

    if (fgets (str1, MAXC, stdin) == NULL) {    /* validate input */
        fprintf (stderr, "error: user canceled input.\n");
        return 1;
    }

    len = strlen (str1);    /* validate string length */
    if (len + 1 == MAXC && str1[len - 1] != '\n') {
        fprintf (stderr, "error: string too long.\n");
        return 1;
    }

    /* separate str1 into words on space ' '.
     * this is the same approach as used on wordsfile.
     * (note: you can use strtok for this purpose) 
     */
    for (i = 0, c = 0; c < (int)len; c++) {
        if (str1[c] == ' ' || str1[c] == '\n') {
            wordsuser[uwords++][i] = 0;
            i = 0;
        }
        else    /* assign char to wordsuser */
            wordsuser[uwords][i++] = str1[c];

        if (i >= TENC) {    /* protect array bounds */
            fprintf (stderr, "error: wordsuser - word too long.\n");
            return 1;
        }
    }
    if (i)  /* handle last word in string */
        wordsuser[uwords++][i] = 0;  /* nul-terminate */

    putchar ('\n');
    for (i = 0; i < uwords; i++) /* output words from file */
        printf ("wordsuser[%d] : %s\n", i, wordsuser[i]);

    printf ("\n Determine if words entered by user are pronouns :\n"
            " ---------------------------------------------------\n\n");
    /* cycle through each word in user input comparing to words from file.
     * if match found, output words as pronoun, otherwise output as
     * not a pronoun.
     */
 for (i = 0; i < uwords; i++) {      /* for each word in wordsuser */
        printf (" %-10s - ", wordsuser[i]); /* output the word */
        for (c = 0; c < fwords; c++) {  /* for each word in wordsfile */
            /* do they match any word in wordsfile (pronouns) ? */
            if (strcmp (wordsuser[i], wordsfile[c]) == 0) {
                printf ("pronoun.\n");
                goto nextword;
            }
        }
        for (c = 0; c < (int)nnouns; c++)   /* do they match a noun? */
            if (strcmp (wordsuser[i], wordsnoun[c]) == 0) {
                printf ("noun.\n");
                goto nextword;
            }

        for (c = 0; c < (int)nverbs; c++)   /* do they match a noun? */
            if (strcmp (wordsuser[i], wordsverb[c]) == 0) {
                printf ("verb.\n");
                goto nextword;
            }
        /*
         *  ALL your remaining tests go here!
         */
        printf ("unclassified.\n");
        nextword:;
    }

    return 0;
}

任何帮助都将非常感激。

1 个答案:

答案 0 :(得分:2)

通过短语来回答你的问题有点受阻。

从哪里开始?让我根据上面的代码和您的数据文件,让您最好地了解您要完成的任务。如果我没有弄错,你想从文件"test.txt"中读取四个单词(代词),然后将每行上的单词分开,以便您可以将它们与用户输入的单词进行比较,以确定是否用户输入的单词是代词。关闭?

虽然strtok通常用于将标记化刺入单独的单词,但是通过从字符串(或文件)的开头手动标记字符串绝对没有错)最后检查沿途的每个角色,并采取必要的措施分别存储单词。您既可以使用指针向下遍历字符串,也可以使用字符串索引来完成相同的操作。

虽然您可以简单地将"test.txt"中的每一行读入单独的存储空间并重复调用fgets(并从每个行中删除尾随的'\n'),但阅读将文件放入缓冲区然后解析它。 (就像任何阵列或内存存储一样,它是 由你决定 ,以确保你不会尝试存储比你有空间更多的字符)。所以 验证 。这也适用于使用任何返回指示成功或失败的函数。验证退货。

使用string.h中的任何功能时,他们希望 nul-terminated 字符串作为输入(例如strlenstrcmp等。) 。当您逐个阅读时,取决于您,以确保您肯定 nul-terminate 您打算用作字符串的每个字符数组,保证最终字符是 nul-character (例如'\0'或只是&#39; 0&#39; - 它们是等价的, nul-character 具有ASCII值0)。

每次填充数组时,您可以通过将 nul-character 指定为最终终止字符来确保每个字符串 nul-terminated - 或 - 如果你只将字符写入数组一次 - 通过小心地将数组初始化为所有0并确保你写入的数字不超过数组中字符总数的一个。

考虑事先需要的变量。如果您有一个文件中的单词和用户的多个单词,那么fwordsuwords(或fcountucount)是有意义的。同样地,用于存储文件中的单词和来自用户的单词的2D数组可以是wordsfilewordsuser(或者您喜欢的任何名称,与您存储的内容存在某种理性关系)。

虽然C99及更高版本不再需要在每个代码块的开头声明所有变量,但有时这并不是一种不好的做法,可以帮助您收集您的想法并防止不需要的和不相关的变量在不断增长你的代码。

虽然不是错误,但C的标准编码样式避免使用camelCaseMixedCase变量名来支持所有小写,同时保留用于宏和常量的大写名称。您的newString已重命名为wordsuser

如果您需要代码中的常量(数组边界,默认文件名等),请在源文件的顶部定义它们。这样,如果需要进行任何调整或更改,您只需一个方便的位置即可进行更改,而无需选择代码的每一行。

最后,逻辑地列出你的代码。如果要打开文件,从中读取文件,然后将文件中的单词分隔到单独的存储中,则在文件的一个部分中执行此操作。不要在整个代码中将它混合在一起。然后fclose你的文件 - 你完成了它。

以下是对您应用上述清理和调整的意图的猜测。请注意,有更短的方法来解决这个问题,但是尝试使操作与您尝试执行的操作保持一致。仔细检查代码并确保理解为什么做了 - 已完成。如果您有疑问,请询问。

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

#define FNAME "test.txt"    /* if you need constants, define them */
#define TENC   10
#define MAXC  100

int main (void) {

    int c = 0, i = 0, ndx = 0,          /* misc. counters & index    */
        fwords = 0,                     /* number of words in file   */
        uwords = 0;                     /* number of words from user */
    size_t len = 0;                     /* string length             */
    char arr[MAXC] = "",                /* storage for file contents */
        str1[MAXC] = "",                /* storage for user string   */
        wordsfile[TENC][TENC] = { "" }, /* separated words from file */
        wordsuser[TENC][TENC] = { "" }; /* separated words from user */
    FILE *fp = fopen (FNAME, "r");

    if (fp == NULL) {       /* validate file open for reading */
        perror (FNAME);
        return 1;
    }

    printf ("\n Reading from '%s' and separating into words by line :\n"
            " --------------------------------------------------------\n\n",
            FNAME);

    /* read characters from file into 'arr' and separate into words
     * by newline into 'wordsfile'. nul-terminate each word. protect
     * all array bounds and against non-POSIX eof.
     */
    while (ndx < MAXC && fwords < TENC && (c = fgetc(fp)) != EOF) {
        if (c == '\n') {    /* separate words in file by line */
            wordsfile[fwords++][i] = 0;    /* nul-terminate */
            i = 0;          /* reset words character count */
        }
        else  /* assign char to both wordsfile & arr */
            wordsfile[fwords][i++] = arr[ndx++] = c;

        if (i >= TENC) {    /* protect array bounds */
            fprintf (stderr, "error: wordsfile - word too long.\n");
            return 1;
        }
    }
    if (i)  /* handle non-POSIX file ending (no '\n') */
        wordsfile[fwords++][i] = 0;  /* nul-terminate */

    fclose (fp);    /* close the file - done with it */

    for (i = 0; i < fwords; i++) /* output words from file */
        printf ("wordsfile[%d] : %s\n", i, wordsfile[i]);

    printf ("\n Split string by space into words :\n"
            " --------------------------------------\n"
            " Input  a string : ");    

    if (fgets (str1, MAXC, stdin) == NULL) {    /* validate input */
        fprintf (stderr, "error: user canceled input.\n");
        return 1;
    }

    len = strlen (str1);    /* validate string length */
    if (len + 1 == MAXC && str1[len - 1] != '\n') {
        fprintf (stderr, "error: string too long.\n");
        return 1;
    }

    /* separate str1 into words on space ' '.
     * this is the same approach as used on wordsfile.
     * (note: you can use strtok for this purpose) 
     */
    for (i = 0, c = 0; c < (int)len; c++) {
        if (str1[c] == ' ' || str1[c] == '\n') {
            wordsuser[uwords++][i] = 0;
            i = 0;
        }
        else    /* assign char to wordsuser */
            wordsuser[uwords][i++] = str1[c];

        if (i >= TENC) {    /* protect array bounds */
            fprintf (stderr, "error: wordsuser - word too long.\n");
            return 1;
        }
    }
    if (i)  /* handle last word in string */
        wordsuser[uwords++][i] = 0;  /* nul-terminate */

    putchar ('\n');
    for (i = 0; i < uwords; i++) /* output words from file */
        printf ("wordsuser[%d] : %s\n", i, wordsuser[i]);

    printf ("\n Determine if words entered by user are pronouns :\n"
            " ---------------------------------------------------\n\n");
    /* cycle through each word in user input comparing to words from file.
     * if match found, output words as pronoun, otherwise output as
     * not a pronoun.
     */
    for (i = 0; i < uwords; i++) {      /* for each word in wordsuser */
        int pronoun = 0;                /* flag for pronoun found */
        for (c = 0; c < fwords; c++) {  /* for each word in wordsfile */
            /* do they match ? */
            if (strcmp (wordsuser[i], wordsfile[c]) == 0) {
                printf (" %-10s - pronoun.\n", wordsuser[i]);
                pronoun = 1;
            }
        }
        if (!pronoun)   /* if no match found */
            printf (" %-10s - not a pronoun.\n", wordsuser[i]);
    }

    return 0;
}

注意:其他错误检查和错误处理可以并且应该添加到您的代码中,上面只是保护数组边界的最小值)

示例使用/输出

以下是使用"test.txt"文件和其他字符串进行代词检查的简短示例。

$ ./bin/splitonspace

 Reading from 'test.txt' and separating into words by line :
 --------------------------------------------------------

wordsfile[0] : we
wordsfile[1] : I
wordsfile[2] : my
wordsfile[3] : you

 Split string by space into words :
 --------------------------------------
 Input  a string : I don't want my dog to have fleas do you

wordsuser[0] : I
wordsuser[1] : don't
wordsuser[2] : want
wordsuser[3] : my
wordsuser[4] : dog
wordsuser[5] : to
wordsuser[6] : have
wordsuser[7] : fleas
wordsuser[8] : do
wordsuser[9] : you

 Determine if words entered by user are pronouns :
 ---------------------------------------------------

 I          - pronoun.
 don't      - not a pronoun.
 want       - not a pronoun.
 my         - pronoun.
 dog        - not a pronoun.
 to         - not a pronoun.
 have       - not a pronoun.
 fleas      - not a pronoun.
 do         - not a pronoun.
 you        - pronoun.

为&#34;名词&#34;等添加其他测试的示例

正如评论中所解释的,所有基本工具(进行任何数量的检查)都在我上面的原始答案中提供。添加额外的检查意味着:

  1. 从其他文件(或来源)中读取其他分类的字词;

  2. 将这些单词存储在另一个数组(或合适的存储空间)中,并知道您拥有的每个类型单词的数量;最后

  3. 将新类型的比较添加到循环中,循环覆盖用户最后提供的所有单词 - 检查新单词列表。

  4. 为防止仅为了此示例的目的而复制另一个文件,我只是添加了一个指向名词 "dog""fleas"的指针数组并更改了如果单词既不是名词代词,则从"not a pronoun""unclassified"的默认邮件。为了为比较名词提供简单的存储,我添加了一个wordsnoun数组(指向字符串文字的指针 - 你将从文件填充普通的2D数组,就像上面的wordsfile所做的那样)。对于这个例子我添加了:

        char arr[MAXC] = "",                /* storage for file contents */
        ...
            *wordsnoun[] = { "dog", "fleas" };  /* nouns - example       */
        size_t len = 0,                     /* string length             */
            nnouns = sizeof wordsnoun / sizeof *wordsnoun;  /* no. nouns */
    

    名词的位置在nnouns中。 (同样注意:我将字符数组声明下方的len声明移到nnouns以及len

    然后,当您循环用户输入的每个单词时,只需在wordsnoun中对每个单词添加一个检查。 (我还添加了goto以防止在匹配发生后进行不必要的比较。例如:

        /* cycle through each word in user input comparing to classification words.
         * if match found, output classification for word, otherwise if no match
         * is found, output "unclassified".
         */
        for (i = 0; i < uwords; i++) {      /* for each word in wordsuser */
            printf (" %-10s - ", wordsuser[i]); /* output the word */
            for (c = 0; c < fwords; c++) {  /* for each word in wordsfile */
                /* do they match any word in wordsfile (pronouns) ? */
                if (strcmp (wordsuser[i], wordsfile[c]) == 0) {
                    printf ("pronoun.\n");
                    goto nextword;
                }
            }
            for (c = 0; c < (int)nnouns; c++)   /* do they match a noun? */
                if (strcmp (wordsuser[i], wordsnoun[c]) == 0) {
                    printf ("noun.\n");
                    goto nextword;
                }
            /*
             *  ALL your remaining tests go here!
             */
            printf ("unclassified.\n");
            nextword:;
        }
    

    示例使用/输出

    进行这些更改会产生以下输出:

    $ ./bin/splitonspace
    
     Reading from 'test.txt' and separating into words by line :
     --------------------------------------------------------
    
    wordsfile[0] : we
    wordsfile[1] : I
    wordsfile[2] : my
    wordsfile[3] : you
    
     Split string by space into words :
     --------------------------------------
     Input a string : I don't want my dog to have fleas do you
     String entered : I don't want my dog to have fleas do you
    
    wordsuser[0] : I
    wordsuser[1] : don't
    wordsuser[2] : want
    wordsuser[3] : my
    wordsuser[4] : dog
    wordsuser[5] : to
    wordsuser[6] : have
    wordsuser[7] : fleas
    wordsuser[8] : do
    wordsuser[9] : you
    
     Determine if words entered by user are pronouns :
     ---------------------------------------------------
    
     I          - pronoun.
     don't      - unclassified.
     want       - unclassified.
     my         - pronoun.
     dog        - noun.
     to         - unclassified.
     have       - unclassified.
     fleas      - noun.
     do         - unclassified.
     you        - pronoun.
    

    添加更多不同类型的分类没有任何魔力,可以根据需要添加更多不同类型的分类。对于您添加的每个新分类,只需按照1, 2 & 3步骤操作即可。 (并记住根据需要调整常量和数组大小)祝你好运。