我必须在我的应用程序中找出/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/