我正在尝试实现计算文本文件中单词数量的函数。
这是我迄今为止的尝试。
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char word[1000];
int count = 0, i;
int *ptr = NULL;
printf("Enter filename: ");
scanf("%s", word);
fp = fopen(word, "r");
while(fscanf(fp, "%s", word) != EOF) //dynamically allocate contents of the file into word
ptr = (int *)malloc(sizeof(int));
for(i = 0; i < 4000; i++)
{
if(word[i] == ' ')
count++;
}
printf("Total: %d", count);
return 0;
}//main
当我使用gcc-进行编译时,我会遇到类似"变量'ptr
'set but not used"的错误,但当我将文件的内容动态分配到word[80]
时,我认为我已经使用了它。
我想我的单词计数器出了严重问题。。。当明显存在200+个单词时,它也返回0。有人能启发我吗?
嗯,但当我将文件的内容动态分配到word[80]中时,我以为我已经使用了它?
不,你一次又一次地设置:
int *ptr = NULL; // <-- pointer is set to null
while(fscanf(fp, "%s", word) != EOF)
ptr = (int *)malloc(sizeof(int)); // ptr is being set to some memory, again and again
// also this could be a nice memory leak
所以这就是为什么你让gcc告诉你"变量'ptr'设置但没有使用",因为你没有使用它
所以问题:
- ptr已设置但未使用
- 将(sizeof int)字节分配给(int*)
- 内存泄漏,不断重写
ptr
fscanf()
返回成功分配的数量,您应该使用它而不是EOFword[]
的长度为1000,但您正在循环到4000
- 通过将
fscanf()
结果放入"单词"中,您不断地覆盖其中的内容 - 你不应该投
malloc()
的回报 "%s"
实际上应该是"%999s"
,以限制输入的长度,但使用1000,我认为无论如何都是安全的
这就是我所看到的,试着修复它们,看看你会得到什么。
不幸的是,您的程序有很多问题。对于初学者来说,"word"上有一个索引溢出(它被分配了1000个字节,但您的索引运行到4000)。
为什么每次在while循环中读取字符串时都要分配一个整数?
你的程序应该看起来更像这样:
char buffer[1000];
int count = 0;
while(fscanf(fp, "%s", buffer) != EOF) count++;
编辑:对不起,我以为你在读汉字,以上应该反映了变化。
这里有很多错误。fscanf(fp, "%s", word)
会从文件中获取一个新单词,并在每次调用时将其存储在单词缓冲区中。while循环没有开/闭大括号,因此您将为从文件中读取的每个单词分配一个新的int*。从文件中读取所有内容后,您将遍历文件中最后一个单词的单词缓冲区并计算空格,但您要迭代4000而不是1000。试着搜索"C++字数",我相信你能在比我键入这个答案更短的时间内找到有效的解决方案。
根据您的评论"将文件的内容动态分配到单词中",您似乎对代码的实际功能有点困惑:
while(fscanf(fp, "%s", word) != EOF)
ptr = (int *)malloc(sizeof(int));
实际上重复调用CCD_ 12直到返回CCD_。尽管每个fscanf
调用都从文件中读取单词并将其存储到临时缓冲区(word
)中,但这个循环的主体毫无意义。它动态分配足够大的内存以容纳1个整数,并使ptr
指向该内存(已分配但从未释放的内存,这也会导致内存泄漏)。
您可以检查fscanf
的返回值是否等于1
,因为此函数"返回成功匹配和分配的输入项目数"。您的while
循环实际上应该是这样的:
while(fscanf(fp, "%s", word) == 1)
count++;
还要注意,char word[1000];
定义了一个长度为1000
的数组,但for
循环有4000次迭代,并且您试图访问超出数组边界的元素,这会导致未定义的行为。此外,for
循环的逻辑似乎更倾向于计算存储在word
中的空间(' '
)。这个循环对你根本没有用,只要去掉它就行了
希望这有帮助:)
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fp;
char word[1000];
int count = 0, i;
/* (why. What are you doing with this?)
int *ptr = NULL;
*/
printf("Enter filename: ");
scanf("%s", word);
fp = fopen(word, "r");
while(fscanf(fp, "%s", word) != EOF) //dynamically allocate contents of the file into word
count++;
/*
ptr = (int *)malloc(sizeof(int));
for(i = 0; i < 4000; i++)
{
if(word[i] == ' ')
count++;
}
*/
printf("Total: %d n", count); // added a newline, always nice to end that way
return 0;
}//main
#include <stdio.h>
int main()
{
FILE *fp;
int count = 0;
char word[15], c;
printf("Enter filename: ");
scanf("%s", word);
fp = fopen(word, "r");
if(fp == NULL)
return -1;
while((c = fgetc(fp)) != EOF) {
if(c == ' ')
count++;
}
fclose(fp);
printf("Total: %d", count+1);
return 0;
}
这真的很简单。
我修改了你的,只是为了向你展示要拿什么。您可以通过对文件运行"wc"并从文件中获取字数来验证它在Linux上是否有效。