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