我想从包含段落,拆分字然后分配给数组的文件中读取文本

时间:2015-04-05 03:07:56

标签: c arrays string readfile

文本文件包含: “查尔斯·达尔文从”双城记“开幕

这是最好的时期,这是最糟糕的时期。这是时代 智慧,这是愚蠢的时代。这是时代的 信仰,这是怀疑的时代。“

我不确定我哪里出错了。

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#define max_words 20
#define max_story_words 1000
#define max_word_length 80

int main()
{
    char story[max_story_words][max_word_length],ch;
    int num_words=1;
    FILE *file_story=fopen("TwoCitiesStory.txt", "r");
    if (file_story==NULL)
        printf("Unable to open %s\n","TwoCitiesStory.txt");
    else{
        ch=fgetc(file_story);
        while(ch!=EOF){
            if(ch==' '||ch=='\n')
                num_words++;
                ch=fgetc(file_story);
        }
        int i=0;
        //assigning each words to story[i]
        while (i<max_story_words && fgets(story[i], max_word_length, file_story) != NULL) {
            if( story[i][strlen(story[i])-1]=='\n'||story[i][strlen(story[i])-1]==' '||story[i][strlen(story[i])-1]==','||
               story[i][strlen(story[i])-1]=='!'||story[i][strlen(story[i])-1]=='.'||story[i][strlen(story[i])-1]==':'||
               story[i][strlen(story[i])-1]==';'||story[i][strlen(story[i])-1]=='?'||story[i][strlen(story[i])-1]=='-'||
               story[i][strlen(story[i])-1]=='?')
                //remove a newline here
                story[i][strlen(story[i])-1]='\0';
            i++;
        }
        for(int i=0;i<num_words;i++){
        printf("story[%d]: %s\n",i,story[i]);
        }
        printf("%d",num_words);
    }
        return (EXIT_SUCCESS);
}

1 个答案:

答案 0 :(得分:1)

您的代码存在的最大问题是(1)在您读取流向file_story计数字的流后,您无法倒回EOF,以及(2)您没有标记每行读取的每一行{在分配给fgets之前,将{1}}转换为单词。会发生什么是story[i]一次读取整行(这是你想要的)。但是,由您决定将每行分成单词并删除标点字符。

要执行此操作,您需要fgetsstrtokstrsep非常适合这项工作。仔细选择分隔列表,您可以将这些行分成单词并同时将单词分配给strtok

另外,为了天堂,让你的代码呼吸......是的,你可以将所有东西塞进去并移除所有空间,这在我的书中很接近混淆。间距行和扩展语法会使您的代码更多更具可读性。 (你甚至可能会发现它有助于让你更容易编码)但是每个人都有自己的代码。如果你喜欢它浓缩,那很好。

如果您有任何疑问,请查看以下内容并告知我们。我更改了代码以将文件名作为参数,因此它不是硬编码的。您运行该程序并将文件名放在命令行上。祝你好运:

story[i]

上方:我选择使用#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define max_words 20 #define max_story_words 1000 #define max_word_length 80 int main (int argc, char **argv) { if (argc < 2 ) { fprintf (stderr, "Error: insufficient input, usage: %s filename\n", argv[0]); return 1; } char story[max_story_words][max_word_length] = {{0}}; char line[max_story_words] = {0}; char *p; char ch = 0; char *punct="\n ,!.:;?-"; int num_words = 1; int i = 0; FILE *file_story = fopen (argv[1], "r"); if (file_story==NULL) { printf("Unable to open '%s'\n",argv[1]); return (EXIT_FAILURE); } /* count words */ while ((ch = fgetc (file_story)) != EOF) { if (ch == ' ' || ch == '\n') num_words++; } /* you already read file_story to EOF, so you must rewind to reset the EOF condition and place the file pointer at the start */ rewind (file_story); i = 0; /* read each line in file */ while (fgets (line, max_word_length, file_story) != NULL) { /* tokenize line into words removing punctuation chars in punct */ for (p = strtok (line, punct); p != NULL; p = strtok (NULL, punct)) { /* convert each char in p to lower-case with tolower */ char *c = p; for (; *c; c++) *c = tolower (*c); /* manually convert each char in p to lower-case */ // char *c = p; /* save start address of p */ // for (; *c; c++) // if ('A' <= *c && *c <= 'Z') // *c += 32; /* copy token (word) to story[i] */ strncpy ((char *)story[i], p, strlen (p)); i++; } } /* output array */ for(i = 0; i < num_words; i++) printf ("story[%d]: %s\n", i, story[i]); printf("\ntotal words: %d\n\n",num_words); return (EXIT_SUCCESS); } 包含代码,将字符转换为小写。如果您只是学习C,那么在开始编写自己的函数之前,最好先熟悉所有字符处理函数。 (我已经离开了手动转换,但注释掉了,所以你也可以从中学习)