【问题标题】:Quicksort on strings and file in C languageC语言对字符串和文件的快速排序
【发布时间】:2015-06-01 10:55:19
【问题描述】:

我有一个关于在文件中的字符串上实现快速排序的问题。

这个练习需要输入你要打开的文件的文件名,最多可以有100个项目。使用函数char filling(FILE* myfile),文件中包含的每一行都通过一个while循环复制到一个数组中,该循环在文件末尾结束。

然后调用函数sort(strings, start, end, leq)对字符串数组进行排序,在函数结束时,将复制到一个名为sorted_myfile的新文件中。

我的问题是:如何测试我的程序是否适用于文件?

在函数char filling 中,声明leq_fn leq 是指声明指向函数typedef bool(* leq_fn )(char *, char *) 的指针,它包含在快速排序的函数中。我希望我给了你所有你需要的信息来帮助我。谢谢你。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "quicksort.h"
#define MAX_LENGTH 100
#define EXTRA_LENGTH 101
#define LENGTH_STRING 255

char filling(FILE *myfile);
char *strings[MAX_LENGTH]; //Array of at most 100 items

char filling(FILE *myfile){
    char *row;
    char new_filename[LENGTH_STRING];
    FILE* sorted_myfile;
    int i=0, start=0, end=MAX_LENGTH-1;
    bool res_cmplen, res_cmpalpha, res_cmpalpha_nocase;
    FILE *sorted_myfile;

   while(i<=EOF){ 
     if(i==EXTRA_LENGTH){
        printf("The file has more than 100 items\n");
     }else{
        row = calloc(LENGTH_STRING, sizeof(char));
        fgets(row, LENGTH_STRING, myfile);
        strings[i]=row;
        i++;
        free(row);
    }
   }
   leq_fn leq;

   leq = cmp_len;
   res_cmplen = (*leq)("hello", "bye");
   leq = cmp_alpha;
   res_cmpalpha = (*leq)("HELLO", "bye");
   leq = cmp_alpha_nocase;
   res_cmpalpha_nocase = (*leq)("hello", "BYE");

   sort(strings, start, end, leq);
   scanf("%s", new_filename);
   sorted_myfile = fopen(new_filename, "w");
   for(i=0;i<end;i++){
     fputs(strings[i], sorted_myfile);
   }

   return 0;
}


int main(void) {
     char filename[LENGTH_STRING]; 
     FILE *myfile;

     printf("What is the file name?\n");
     scanf("%s", filename);
     myfile =  fopen(filename, "r");

     if(ferror(myfile)!=0){
       printf("The file doesn't exist\n");
     }else{
       filling(myfile);
    }

  return 0;
}

【问题讨论】:

  • filling函数中,循环不会被迭代一次。宏EOF 通常定义为-1,而0 &lt;= -1 永远不会为真。另外,要检查文件是否正确打开,需要检查返回的指针是否为NULL,而不是调用ferror,除了文件不存在之外,可能还有很多其他问题。
  • @JoachimPileborg 所以在 while 循环中,变量 i 将被初始化为 -1?
  • 另外,你的代码中有未定义的行为,你首先使用calloc分配内存,复制指针(但不是指针指向) 然后释放刚刚分配的内存,让指针指向未分配的内存。以任何方式使用该指针都会导致未定义的行为。
  • 不,当i 小于MAX_LENGTHstrings 数组的大小)时,您应该循环。 并且还检查fgets返回的内容,因此一旦到达文件末尾就不会进行迭代。
  • 程序的工作目录和文件所在的目录一样吗?如果您使用某种 IDE(集成开发环境),那么您应该检查项目设置以确保。

标签: c file quicksort


【解决方案1】:

我首先要解决这些问题:

  1. char *row; 更改为char *row = NULL;
  2. 同样将FILE* sorted_myfile;改为FILE* sorted_myfile = NULL;
  3. 更改bool res_cmplen, res_cmpalpha, res_cmpalpha_nocase;
    bool res_cmplen = 0, res_cmpalpha = 0, res_cmpalpha_nocase = 0;
    bool res_cmplen = 1, res_cmpalpha = 1, res_cmpalpha_nocase = 1;
    取决于实施更安全的方法。
  4. FILE *sorted_myfile; 更改为FILE *sorted_myfile = NULL;
  5. main() 中将FILE *myfile; 更改为FILE *myfile = NULL;
  6. free(row); row 成为一个悬空指针后,您按原样使用它,然后在循环的最后一次迭代中,您保持原样,这将调用未定义的行为。所以,在释放内存后执行row = NULL;
  7. char *strings[MAX_LENGTH]; 不是 //Array of at most 100 items,而是 //array of MAX_LENGTH pointers。这里发生了什么:strings[i]=row;
  8. 在下面的sn-p中:

    while(i<=EOF){ 
       if(i==EXTRA_LENGTH){  
          printf("The file has more than 100 items\n");  
       }else{  
          row = calloc(LENGTH_STRING, sizeof(char));  
          fgets(row, LENGTH_STRING, myfile);  
          strings[i]=row;  
          i++;  
          free(row);  
       }
     }
    

    ielse{} 条件下递增,if(i==EXTRA_LENGTH) 计算结果为真,即如果i 等于EXTRA_LENGTH,则不会递增或修改,因为这只发生在else{} 中。所以当i == 255时,你的代码永远不会进入else{}条件,只会无限打印“文件有超过100个项目”

  9. 这是一个小问题,但是,在main() 我可以看到myfile = fopen(filename, "r");,这会打开文件。美好的。虽然我看不到你什么时候关闭它,如果你这样做的话。可能在某处缺少fclose();

【讨论】:

  • 6.由于在排序操作期间内存需要保持分配状态,因此free 不应该在之后执行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多