以下代码为什么报段错误int system__popen(const char *cmd, char *cmdresult, int resultlen) { FILE *fp=NULL; if(cmd == NULL) { printf("system input error!!!\n"); return -1; } fp=popen(cmd,"r"); if(NULL == fp) { printf("system popen error cmd :%s!!!\n", cmd); return -1; } if(NULL != cmdresult) { fread(cmdresult,1,resultlen,fp); } pclose(fp); return 0; } int main() { char str[1024]; system__popen("awk '{print $2}' /proc/mtd | tail -n +2", str, sizeof(str)); printf("%s\n",str); char *str_array[20]; // 假设字符串数组最多存储10个子字符串 int i = 0; char *p = strtok(str, "\n"); // 第一次调用strtok时,传入原字符串和分隔符 while (p != NULL) { str_array[i++] = p; // 将分割得到的子字符串存储到字符串数组中 p = strtok(NULL, "\n"); // 继续调用strtok,传入NULL表示继续处理原字符串,直到处理完所有子字符串 } // 输出字符串数组中的内容 for (int j = 0; j < i; j++) { printf("%s\n", str_array[j]); } return 0; }
时间: 2024-03-21 14:38:26 浏览: 62
fork、exec系列与system、popen区别.rar_UNIX popen_linux system pop_pop
该代码有可能在 `fread()` 函数中出现段错误,原因是 `fread()` 函数在读取文件时,可能无法读取完整的 `resultlen` 个字节,导致读取越界,从而导致段错误。
解决该问题的方法是,在调用 `fread()` 函数前,先获取实际读取到的字节数,然后将其与 `resultlen` 取较小值,作为 `fread()` 函数的第三个参数。具体实现代码如下:
```c
int system__popen(const char *cmd, char *cmdresult, int resultlen) {
FILE *fp=NULL;
if(cmd == NULL)
{
printf("system input error!!!\n");
return -1;
}
fp=popen(cmd,"r");
if(NULL == fp)
{
printf("system popen error cmd :%s!!!\n", cmd);
return -1;
}
if(NULL != cmdresult)
{
int bytes_read = fread(cmdresult, 1, resultlen - 1, fp); // 读取实际的字节数
cmdresult[bytes_read] = '\0'; // 将读取到的内容以字符串形式保存
}
pclose(fp);
return 0;
}
int main() {
char str[1024];
system__popen("awk '{print $2}' /proc/mtd | tail -n +2", str, sizeof(str));
printf("%s\n",str);
char *str_array[20]; // 假设字符串数组最多存储10个子字符串
int i = 0;
char *p = strtok(str, "\n"); // 第一次调用strtok时,传入原字符串和分隔符
while (p != NULL) {
str_array[i++] = p; // 将分割得到的子字符串存储到字符串数组中
p = strtok(NULL, "\n"); // 继续调用strtok,传入NULL表示继续处理原字符串,直到处理完所有子字符串
}
// 输出字符串数组中的内容
for (int j = 0; j < i; j++) {
printf("%s\n", str_array[j]);
}
return 0;
}
```
这样就可以避免段错误的问题,同时保证 `cmdresult` 中的字符串以 null 结尾,可以正确进行后续的字符串操作。
阅读全文