Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C语言中对文件中的字符进行排序_C_String_File_Frequency - Fatal编程技术网

在C语言中对文件中的字符进行排序

在C语言中对文件中的字符进行排序,c,string,file,frequency,C,String,File,Frequency,如何在不使用其他文件的情况下对文件中的字符进行排序?我一直在考虑把它们保存在一个字符串中,但是如果有很多字符呢?此外,我一直在考虑创建一个基于ASCII码的频率数组,但同样,该文件可能有数百MB 谢谢大家! 我假设character是指C所称的character;多字节和宽字符集超出范围。在这种情况下,只有UCHAR_MAX+1个字符,通常是256个不同的字符,这是一个足够小的字符集。基本上,您需要做的是读取整个文件,计算每个字符的出现次数,并按显示的次数打印每个字符。使用无符号长整型数组,因为

如何在不使用其他文件的情况下对文件中的字符进行排序?我一直在考虑把它们保存在一个字符串中,但是如果有很多字符呢?此外,我一直在考虑创建一个基于ASCII码的频率数组,但同样,该文件可能有数百MB


谢谢大家!

我假设character是指C所称的character;多字节和宽字符集超出范围。在这种情况下,只有UCHAR_MAX+1个字符,通常是256个不同的字符,这是一个足够小的字符集。基本上,您需要做的是读取整个文件,计算每个字符的出现次数,并按显示的次数打印每个字符。使用无符号长整型数组,因为它比ftell可以返回的任何偏移量都大,并将其设为UCHAR_MAX+1个元素长,因为这是可以使用的不同字符数

#include <stdio.h>
#include <stdlib.h>  // for EXIT_FAILURE
#include <limits.h>  // for *_MAX

// "unsigned long int" chosen to match the ftell() limit,
// and numeric variables at top level start out zeroed
unsigned long int occurrences[UCHAR_MAX + 1];

// static assertion to make sure we're on a "sane" platform
// with INT_MAX larger than UCHAR_MAX
extern char staticassert1[INT_MAX > UCHAR_MAX ? 1 : -1];

int main(const int argc, const char *const *argv) {
  FILE *infp = NULL;
  int ch;

  if (argc < 2) {  // ensure a filename was provided
    fputs("error: no filename\n", stderr);
    return EXIT_FAILURE;
  }
  infp = fopen(argv[1], "rt");
  if (!infp) {  // ensure the file can be read
    perror(argv[1]);
    return EXIT_FAILURE;
  }

  // count each character; EOF is a value distinct from
  // all characters
  for(ch = fgetc(infp); ch != EOF; ch = fgetc(infp)) {
    // cast to unsigned because arrays have no negative index
    occurrences[(unsigned char)ch] += 1;
  }

  // once ch becomes EOF, the file has been read
  // to either its end or an error
  if (ferror(infp)) {
    fclose(infp);
    perror(argv[1]);
    return EXIT_FAILURE;
  }

  // close the successfully read file
  fclose(infp);
  infp = NULL;  // it's good practice to cut off dangling pointers early

  // now print all characters in the file in sorted order
  for (ch = 0; ch <= UCHAR_MAX; ++ch) {
    for (; occurrences[ch] > 0; --occurrences[ch]) {
      fputc(ch, stdout);
    }
  }

  return 0;
}

它只是简单地计算每个字符。大小\u t计数器[256]={0};。。计数器[c]++;你真的想对字符进行排序吗?那么Hello world排序的文件将是Dehlloorw?你真的是指角色吗?如果是这样的话,假设ascii码只能有255个,那么保持一个频率计数——如果您对每个bucket使用int,那么仍然只有1k。他们把它们按顺序写出来,重复每个字符在文件中出现的次数是的,我的意思是字符:Hello World将是Hdellloor非常感谢你非常详细的回答。在您的最后一行中,标准输出不在屏幕上打印字符吗?@Stefan标准输出流将字符写入操作系统定义的标准输出。在带有屏幕的类似工作站的系统上,如Windows和GNU/Linux,stdout通常是终端仿真器,但它可以重定向到文件或管道的一侧。请随时澄清您的问题,说明您希望将排序结果写入何处。你的意思是把它们写在同一个文件里吗?如果不清楚的话,很抱歉。是的,我的意思是将它们保存在同一个文件中。@Stefan您可以更改此程序以使用fopen打开输出文件,并将字符写入该文件,而不是写入标准输出。但是,写入刚才读取的文件名是不安全的,因为如果计算机在中间失去电源,则无法恢复原始文件。@斯特凡不使用没有正确格式字符串的PROTF家族函数!这是一个坏习惯,可能导致并已经导致安全漏洞。在C标准库参考中查找rewind和fputc。