C编程:一个计算文本文件中单词数的程序?

时间:2013-02-20 19:29:53

标签: c arrays file-io malloc

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

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

#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'设置但未使用”,但我认为我在动态分配内容时使用了它将文件放入word[80]

我认为我的单词计数器出现严重错误...当有200多个单词时,它也会返回0。有人可以赐教我吗?

7 个答案:

答案 0 :(得分: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()结果放入“word”,你不断覆盖那里的内容
  7. 您不应该投回malloc()
  8. 的回报
  9. "%s"应该"%999s"来限制输入的长度,但是1000我觉得你还是安全的。
  10. 这就是我所能看到的全部,尝试修复它们,看看你得到了什么。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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

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

char buffer[1000];
int count = 0;
while(fscanf(fp, "%s", buffer) != EOF) count++;
编辑:对不起,我以为你在读字,上面的内容现在应该反映出这一变化。

答案 3 :(得分: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)。这个循环根本不适用于你,只是摆脱它。

希望这会有所帮助:)

答案 4 :(得分: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;
}

这真的很简单。

答案 5 :(得分: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

答案 6 :(得分:0)

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