我试图找出使用c代码的文件类型,这里是代码
char *get_file_type(char *path, char *filename)
{
FILE *fp;
char command[100];
char file_details[100];
char *filetype;
sprintf(command, "file -i %s%s", path, filename);
fp = popen(command, "r");
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
while (fgets(file_details, sizeof(file_details)-1, fp) != NULL) {
filetype = (strtok(strstr(file_details, " "), ";"));
}
pclose(fp);
return filetype;
}
这里不是声明命令[],我可以使用*命令吗?我试图使用它,但它抛出异常。我们不需要释放像command []声明的变量吗?如果是的话怎么样?
答案 0 :(得分:11)
声明数组时:
char command[100];
编译器为其分配内存(在本例中为100个字符),command
指向该内存的开头。您可以访问已分配的内存:
command[0] = 'a'; // OK
command[99] = 'A'; // OK
command[100] = 'Z'; // Error: out of bounds
但您无法更改command
的价值:
command = NULL; // Compile-time error
当command
超出范围时,内存将自动释放。
声明指针时:
char *commandptr;
你只创建一个指向char
的变量,但它还没有指向任何东西。试图在不初始化的情况下使用它是一个错误:
commandptr[0] = 'A'; // Undefined behaviour; probably a segfault
您需要使用malloc
自行分配内存:
commandptr = malloc(100);
if (commandptr) {
// Always check that the return value of malloc() is not NULL
commandptr[0] = 'A'; // Now you can use the allocated memory
}
并在完成后将其释放:
free(commandptr);
答案 1 :(得分:5)
您可以使用char *command;
,但是,您必须为command
分配一些内存以通过调用malloc()
来引用,当您完成该内存时,它必须通过拨打free()
再次释放。
正如您所看到的,这比使用固定大小的数组要多得多(正如您现在所做的那样),但它也可以更加安全,因为您可以创建一个大小合适的缓冲区,而不是希望命令的总长度不超过100个字符。
除此之外,您的代码有一个问题:函数返回的filetype
指针指向数组file_details
中的某个位置,但编译器在执行时会清除该数组。 return
语句,因此函数返回的指针指的是一些标记为“可以用于其他目的”的内存。
如果get_file_type
的结果一次仅对一个文件有效不是问题,您可以将file_details
数组声明为static
,这样就可以了保留了对函数的调用。
答案 2 :(得分:1)
你为什么要改变它?对于临时缓冲区,人们通常使用[]声明数组,因此他们不必担心垃圾处理。