文本文件包含: “查尔斯·达尔文从”双城记“开幕
这是最好的时期,这是最糟糕的时期。这是时代 智慧,这是愚蠢的时代。这是时代的 信仰,这是怀疑的时代。“
我不确定我哪里出错了。
#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);
}
答案 0 :(得分:1)
您的代码存在的最大问题是(1)在您读取流向file_story
计数字的流后,您无法倒回EOF
,以及(2)您没有标记每行读取的每一行{在分配给fgets
之前,将{1}}转换为单词。会发生什么是story[i]
一次读取整行(这是你想要的)。但是,由您决定将每行分成单词并删除标点字符。
要执行此操作,您需要fgets
或strtok
。 strsep
非常适合这项工作。仔细选择分隔列表,您可以将这些行分成单词并同时将单词分配给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,那么在开始编写自己的函数之前,最好先熟悉所有字符处理函数。 (我已经离开了手动转换,但注释掉了,所以你也可以从中学习)