如果你必须写 C,它不需要那么长或那么复杂。如果您忽略错误检查,您可以简化它。
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern void err_exit(const char *fmt, ...);
typedef struct data
{
char *line;
int key;
} data;
static int cmp_data(const void *v1, const void *v2)
{
const data *d1 = v1;
const data *d2 = v2;
if (d1->key < d2->key)
return -1;
else if (d1->key > d2->key)
return +1;
else
return 0;
}
int main(void)
{
char buffer[4096];
data *array = 0;
size_t array_len = 0;
size_t array_max = 0;
while (fgets(buffer, sizeof(buffer), stdin) != 0)
{
if (array_len >= array_max)
{
size_t new_size = (array_max + 2) * 2;
void *space = realloc(array, new_size * sizeof(data));
if (space == 0)
err_exit("Out of memory (1)");
array = space;
array_max = new_size;
}
array[array_len].line = strdup(buffer);
if (array[array_len].line == 0)
err_exit("Out of memory (2)");
if (sscanf(array[array_len].line, "%*s %d", &array[array_len].key) != 1)
err_exit("Format error - no number in right place in: %.20s...\n",
array[array_len].line);
//printf("%3zu:%.10d: %s", array_len, array[array_len].key,
// array[array_len].line);
array_len++;
}
qsort(array, array_len, sizeof(data), cmp_data);
for (size_t i = 0; i < array_len; i++)
fputs(array[i].line, stdout);
return 0;
}
void err_exit(const char *fmt, ...)
{
int errnum = errno;
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
if (errnum != 0)
fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
putc('\n', stderr);
exit(EXIT_FAILURE);
}
keysort — 在文件排序时覆盖文件
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void sort_file(const char *i_file, const char *o_file);
int main(int argc, char **argv)
{
if (argc > 1)
{
for (int i = 1; i < argc; i++)
sort_file(argv[i], argv[i]);
}
else
sort_file("/dev/stdin", "/dev/stdout");
return 0;
}
typedef struct data
{
char *line;
int key;
} data;
static int cmp_data(const void *v1, const void *v2)
{
const data *d1 = v1;
const data *d2 = v2;
if (d1->key < d2->key)
return -1;
else if (d1->key > d2->key)
return +1;
else
return 0;
}
static void err_exit(const char *fmt, ...)
{
int errnum = errno;
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
if (errnum != 0)
fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
putc('\n', stderr);
exit(EXIT_FAILURE);
}
void sort_file(const char *i_file, const char *o_file)
{
char buffer[4096];
data *array = 0;
size_t array_len = 0;
size_t array_max = 0;
FILE *i_fp = fopen(i_file, "r");
if (i_fp == 0)
err_exit("Failed to open file %s for reading", i_file);
while (fgets(buffer, sizeof(buffer), i_fp) != 0)
{
if (array_len >= array_max)
{
size_t new_size = (array_max + 2) * 2;
void *space = realloc(array, new_size * sizeof(data));
if (space == 0)
err_exit("Out of memory (1)");
array = space;
array_max = new_size;
}
array[array_len].line = strdup(buffer);
if (array[array_len].line == 0)
err_exit("Out of memory (2)");
if (sscanf(array[array_len].line, "%*s %d", &array[array_len].key) != 1)
err_exit("Format error - no number in right place in: %.20s...\n",
array[array_len].line);
//printf("%3zu:%.10d: %s", array_len, array[array_len].key,
// array[array_len].line);
array_len++;
}
fclose(i_fp);
qsort(array, array_len, sizeof(data), cmp_data);
FILE *o_fp = fopen(o_file, "w");
if (o_fp == 0)
err_exit("Failed to open file %s for writing", o_file);
for (size_t i = 0; i < array_len; i++)
fputs(array[i].line, o_fp);
fclose(o_fp);
}
如果您的系统不支持/dev/stdin
and /dev/stdout
,那么您必须将接口修改为sort_file()
,可能为:
void sort_file(const char *i_file, FILE *ifp, const char *o_file, FILE *ofp);
然后,您决定如果ifp
不为空,则将其用于输入 - 否则您打开由i_file
. 类似的输出:如果ofp
不为空,则使用它 - 否则,您打开由o_file
. 的变化main()
和身体的变化sort_file()
是微不足道的。