c - 系统命令的打开和输出

标签 c arrays linux popen

我必须在我的应用程序中找出/mnt/中的可用空间。我写了下面的代码。但是,execute_cmd 有时会返回实际输出之外的垃圾。例如:4.5K(后跟垃圾)。我哪里错了?有人可以回顾并让我知道为什么 execute_cmd 最后返回一个垃圾字节吗?我如何改进代码?

char *execute_cmd(char *cmd)
{
        FILE *fp;
        char path[100];
        int ii = 0;
        //char ii = 0;
        char *buffer = malloc(1024);
        char len = 0;

        /* Open the command for reading. */
        fp = popen(cmd, "r");
        if (fp == NULL) {
        printf("Failed to run command\n" );
        exit(1);
        }
        printf("Running command is: %s\n", cmd);

        memset(buffer, 0, sizeof(buffer));

        do {
        len = fread(path, 100, 1, fp); /* Is it okay to use fread? I do not know how many bytes to read as this function is a generic function which can be used for executing any command */
        strcat(buffer,path);
        printf("Number of bytes is: %d\n", len);
        } while (len != 0);

        len = strlen(buffer);
        printf("Buffer contents are: %s %d\n", buffer,len);

        /* close */
        pclose(fp);
}

void main()
{
        char *buffer = "df -h  | grep \"/mnt\" | awk '{ print $4}'"; /* FIXME */
        char len;
        char units;
        float number;
        char dummy = 0;
        char *avail_space;

        avail_space = execute_cmd(buffer);
        len = strlen(avail_space);
        units = avail_space[len - 1];

        printf("Available space is: %s %d %c end here\n", avail_space, len, units);
        number = strtof(avail_space, NULL);
        printf("Number is: %f\n", number);
}

最佳答案

sizeof(buffer)sizeof(char*),大概是 8(也可能是 4)。所以你的 memset 只清除了一点点 buffer。但是随着您使用 fread,需要清除的不仅仅是 buffer;这是临时的路径

path 等未初始化的局部变量不是零初始化的。您可以使用 memset(path, 0, sizeof(path)); 来清除它 - 这里 sizeof 有效,因为 path 确实是一个数组——但更简单的是在声明中对其进行初始化:char path[100] = "";

由于 fread 不会以 NUL 终止它读取的内容,因此它后面可能有任意垃圾,从而导致 strcat 未定义的行为。事实上,strcat 是完全没有必要的,而且是在浪费周期。您知道您读取了多少数据(在 len 中),因此您确切地知道从哪里读取下一个 block ,并且您可以直接这样做而无需临时缓冲区和副本。

为了将来引用,如果您计划调用 malloc 然后使用 memset 清除分配的区域,您应该改用 calloc .这就是它的用途。

关于c - 系统命令的打开和输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50492852/

相关文章:

c - 这个错误是什么意思: `somefile.c:200: error: the frame size of 1032 bytes is larger than 1024 bytes` ?

c - 为什么 gid_t 不在我的 sys/types 头文件中?

c - 是否可以使用 GreenHills 使用与数值常量不同的东西进行预处理评估?

c - 如何获取数组中元素的个数?

ruby - 如何在 Ruby 中模仿 execl()

objective-c - 将 objective-C 应用程序切换到 x86_64 并且 sizeof 返回错误结果

javascript - Google Maps API v3 For 循环问题

php - 使用正则表达式匹配作为数组指针

c++ - 列出在 Linux 上使用 C/C++ 执行的程序中的共享库

c - 如果我重复运行这个程序,为什么在 seg-fault 之前打印的最后一个数字会有所不同?