在文件中找到N个字母的单词

时间:2015-11-07 10:14:03

标签: c

我有一个问题,我在C语言中的程序必须找到带有N个字母的单词,计算它们并按字典顺序对它们进行排序并将它们保存到另一个文件中。我已经完成了前两件事,但是对它们进行排序并保存到文件中并不起作用。它只将最后一个单词保存到第二个文件中...你知道为什么吗?

这是我的代码:

#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <stddef.h>
#include <string.h>

int main()
{
FILE *r, *fp;
char ch[100];
int n,i,j,x=0;


r=fopen("text.txt","r");

fgets(ch, 100, r);



char *s = ch;
char *p = s;
printf("Give the length of word: ");
scanf("%d",&n);
printf("\n\nWords with %d letters: \n\n",n);
    while (*p) {

        char *start;
        int len;

        while (*p && isspace(*p))
            ++p;
        start = p; 

        while (*p && !isspace(*p))
            ++p;

        len = p - start;
        fp=fopen("text2.txt","w");
        if (len == n) {

            printf("%.*s\n", len, start);
              x++;
            fprintf(fp,"%.*s",len, start);
        }    
    }        
printf("\nNumber of words: %d ",x);
fclose(fp);

getch();      
fclose(r);  
}

我的输入文件:

hi my name is Zsolt this program if for displaying words with N letters count them and sort them alphabeticaly a save them to an another file

1 个答案:

答案 0 :(得分:4)

这是因为你在while循环的每次迭代中打开text2.txt。而且,如果你看一下documentation状态,你可以用模式"w"打开它:

  

:为输出操作创建一个空文件。如果已存在同名文件,则会丢弃其内容,并将该文件视为新的空文件。

所以正在发生的事情是,在每次迭代时,你打开文件,丢弃之前的任何内容,(在第一次迭代之后将是一个包含单个单词的文件)。

相反,你应该在进入while循环之前打开它。

此外,您声明在将其写入新文件之前,您希望对按字典顺序排列的单词进行排序。如果您的代码已经按照您的意图编写了单词,那么它们将按照它们出现在原始文件中的顺序,而不是字典顺序。最好将指针保存到数组中的n长度字,对该数组进行排序,然后将其全部写入输出文件中。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX_WORDS 100

int
qstrcmp(const void *a, const void *b)
{
  const char
    *s = *(const char **)a,
    *t = *(const char **)b;

  return strcmp(s, t);
}

int
main()
{
  FILE *input, *output;
  input = fopen("text.txt", "r");

  // Get length to filter by
  unsigned long n;
  scanf("%lu", &n);

  char *words[MAX_WORDS];
  int i = 0;

  // Find words of correct length
  char buf[100];
  while (fscanf(input, "%99s", buf) != EOF) {
    // Protect from buffer overflow
    if (i >= MAX_WORDS) {
      printf("Too many words!");
      break;
    }

    if (strlen(buf) == n) {
      words[i++] = strncpy(malloc(n+1), buf, n+1);
    }
  }
  fclose(input);

  // Sort in lexicographical order.
  qsort(words, i, sizeof(char *), qstrcmp);

  // Write to output
  output = fopen("text2.txt", "w");
  for (int j = 0; j < i; ++j) {
    fprintf(output, "%s\n", words[j]);
  }
  fclose(output);

  // Print number found.
  printf("Found %d word%s of length %lu.\n", i, i == 1 ? "": "s", n);

  return 0;
}

实施说明

  • 使用"stdlib.h"中的qsort进行排序。
  • 注意缓冲区溢出!在这种情况下,我只是保释,但也可以为words数组重新分配内存。
  • 请记住在保存单词时复制空字节。
  • qsort将对其排序的数组元素的引用传递给其比较器函数,因此它将传递const char **类型的值,这就是为什么我们需要使用{{1} } wrapper function。