2

我正在尝试实现计算文本文件中单词数的函数。

到目前为止,这是我的尝试。

#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- 编译时,我得到了类似"variable ' ptr' set but not used" 之类的错误,但我以为我在将文件内容动态分配到word[80].

我认为我的单词计数器有严重问题......当明显有 200 多个单词时,它也会返回 0。有人可以启发我吗?

4

7 回答 7

1

嗯,但我以为我在将文件内容动态分配到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'设置但没有使用”,因为你不使用它。

所以问题:

  1. ptr 已设置但未使用
  2. 将 (sizeof int) 字节分配给 (int *)
  3. 内存泄漏,不断过度写入ptr
  4. fscanf()返回成功分配的数量,您应该使用它而不是 EOF
  5. word[]长度为 1000,但您正在循环到4000
  6. 通过将fscanf()结果放入“单词”中,您会不断覆盖其中的内容
  7. 你不应该放弃malloc()
  8. "%s"应该真的是"%999s"限制输入的长度,但是 1000 我认为无论如何你都是安全的。

这就是我从头顶上看到的全部内容,尝试修复它们,看看你会得到什么。

于 2013-02-20T19:42:27.537 回答
0
#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;
}

这真的很简单。

于 2013-02-20T19:46:55.380 回答
0

你这里有很多问题。fscanf(fp, "%s", word)每次调用时都会从文件中抓取一个新单词并将其存储在单词缓冲区中。您的 while 循环没有打开/关闭大括号,因此对于您从文件中读取的每个单词,您将分配一个新的 int*。从文件中读取所有内容后,您将遍历文件中最后一个单词的单词缓冲区并计算空格,但您迭代的是 4000 而不是 1000。尝试搜索“C++ word count”而且我相信您将能够在比我输入此答案的时间更短的时间内找到有效的解决方案。

于 2013-02-20T19:34:50.233 回答
0

从您的评论“将文件的内容动态分配到单词中”来看,您似乎对代码的实际作用有些困惑:

while(fscanf(fp, "%s", word) != EOF)
    ptr = (int *)malloc(sizeof(int));

实际上重复调用fscanf直到EOF返回。尽管每次fscanf调用都会从文件中读取单词并将其存储到临时缓冲区 ( word) 中,但这个循环的主体没有任何意义。它动态分配足够大的内存以容纳 1 个整数并ptr指向该内存(已分配但从未释放的内存,这也会产生内存泄漏)。

您可以检查返回值fscanf是否等于1,因为此函数“返回成功匹配和分配的输入项的数量”。您的while循环实际上应该如下所示:

while(fscanf(fp, "%s", word) == 1)
    count++;

另请注意,您char word[1000];定义了一个长度数组1000,但您的for循环有 4000 次迭代,并且您试图访问数组边界之外的元素,这会导致未定义的行为。此外,您的循环逻辑for似乎更倾向于计算' '存储在word. 这个循环对你一点用处都没有,把它去掉就行了。

希望这可以帮助 :)

于 2013-02-20T19:45:07.367 回答
0
#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
于 2013-02-20T19:53:35.060 回答
0

我修改了你的只是为了告诉你要拿出什么。您可以通过对文件运行“wc”并从文件中获取字数来验证它在 Linux 上是否有效。

于 2013-02-20T19:59:07.677 回答
0

不幸的是,您的程序有很多问题。对于初学者来说,'word' 上有一个索引溢出(它分配了 1000 个字节,但你的索引运行到 4000)。

为什么每次在 while 循环中读取字符串时都分配一个整数?

你的程序应该看起来更像这样:

char buffer[1000];
int count = 0;
while(fscanf(fp, "%s", buffer) != EOF) count++;

编辑:对不起,我以为你在读字符,上面现在应该反映了变化。

于 2013-02-20T19:36:20.783 回答