正如标题所说,我需要编写一个小程序来读取标准输入的数据,对其进行排序,然后将其发送到标准输出.程序应该使用1个参数来告诉它一条记录有多长(以字节为单位).这是我测试它的方式:
printf 'D\x00C\x00\x00B\x00A' | ./binsort 2 | od -c
以上应输出如下内容:
0000000 \0 A \0 B C \0 D \0 0000010
这是我到目前为止(binsort.c
):
#include#include #include using namespace std; void print_usage() { printf("%s\n", "Usage: "); } int compare (const void * a, const void * b) // the compare function for qsort... might need some work { return ( *(int*)a - *(int*)b ); } int main(int argc, char *argv[]) { if (argc != 2 || stdin == NULL) // check for argument and piped input { print_usage(); exit(EXIT_FAILURE); } int entry_size = atoi(argv[1]); if (entry_size <= 0 || entry_size >= INT_MAX) // check for valid range of entry size { print_usage(); exit(EXIT_FAILURE); } char *input = new char[entry_size]; // to hold single record while (fgets(input, entry_size, stdin) != NULL) { printf("%s", input); // output single record we just read } exit(EXIT_SUCCESS); }
然后编译g++ binsort.c -o binsort
.
以上编译但不输出printf
发送给它的数据.它应该以2字节的块输出...就像D\0 C\0 \0B \0A
...但它没有.
我正在考虑使用qsort
在已malloc/realloc
分配的数组上进行排序.但是,我从来没有经历过这些,实际上是在这个小工具上敲了几天.有人可以帮忙吗?
PS人们问这是否是家庭作业......不是 - 我公司的开发人员想用它来调试他们项目的输出.
不要使用scanf()
和printf()
.这些应该与文本数据一起使用.既然你处理二进制数据,而不是你要使用较低级别fread()
和fwrite()
功能.由于您不知道有多少总数据,因此您必须使用动态数据结构(例如可调整大小的数组)来存储输入.您无法在线处理数据 - 您必须全部读取数据,对其进行排序,然后将其写回.你的排序功能也是错误的 - 你只是比较每条记录的前4个字节,如果记录大小不是4个字节,那就错了.请memcmp()
改用.
这应该工作:
char *input = NULL; size_t input_size = 0; int num_items = 0; int entry_size; int compare_func(const void *e1, const void *e2) { return memcmp(e1, e2, entry_size); } int main(int argc, char **argv) { // ... char *datum = malloc(entry_size); // check for NULL input_size = 4096; input = malloc(input_size); // check for NULL while(1) { if(fread(datum, 1, entry_size, stdin) < entry_size) break; size_t new_size = (num_items + 1) * entry_size; if(new_size > input_size) { input = realloc(input, input_size * 2); // check for NULL input_size *= 2; } memcpy(input + num_items * entry_size, datum, entry_size); num_items++; } qsort(input, num_items, entry_size, compare_func); fwrite(input, entry_size, num_items, stdout); return 0; }