当前位置:  开发笔记 > 小程序 > 正文

使用stdio在Linux中读取和排序管道数据

如何解决《使用stdio在Linux中读取和排序管道数据》经验,为你挑选了1个好方法。

正如标题所说,我需要编写一个小程序来读取标准输入的数据,对其进行排序,然后将其发送到标准输出.程序应该使用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人们问这是否是家庭作业......不是 - 我公司的开发人员想用它来调试他们项目的输出.



1> Adam Rosenfi..:

不要使用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;
}

推荐阅读
手机用户2402851155
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有