我编写了一个使用fread
练习的程序。我正在将命令传递给popen
并使用fread
读取输出并存储到未初始化的char数组中。最后,我打印数组的内容以及将其写入另一个文件。打印(stdout中的输出)工作正常但是当我检查文件的内容时,它在实际输出后有很多垃圾。有什么理由在stdout中运行良好吗?
这是我的代码:
#include <stdio.h>
void fread_s(char *res, int res_size,char *cmd)
{
char *r;
int size;
FILE *fp=popen(cmd,"r");
if(fp==NULL)
return;
size=fread(res,res_size,1,fp);
pclose(fp);
}
int main()
{
char cmd[500];
fread_s(cmd,sizeof(cmd),"ls -lh i*");
puts(cmd);
FILE *fp=fopen("opfile","a+");
if(fp==NULL)
return;
fwrite(cmd,sizeof(cmd),1,fp);
}
答案 0 :(得分:4)
您看到的char
数组不会因空终止而产生不必要的副作用。变化:
size=fread(res,res_size,1,fp);
到
size=fread(res,res_size,1,fp);
res[size] = '\0';
另外,请确保res_size
小于sizeof(cmd)
。否则,您可能会size
sizeof(cmd)
,因此
res[size] = '\0';
将使用越界索引修改数组。
更改
fread_s(cmd,sizeof(cmd),"ls -lh i*");
到
fread_s(cmd,sizeof(cmd)-1,"ls -lh i*");
或更改
size=fread(res,res_size,1,fp);
到
size=fread(res,res_size-1,1,fp);
答案 1 :(得分:2)
代码有size=fread(res,res_size,1,fp)
,但不使用size
,表示读取的元素数。
即使读取的数据包含嵌入的空字符,以下内容仍然有效。
// Return the number of elements read
size_t fread_s(char *res, int res_size,char *cmd) {
char *r;
size_t size;
FILE *fp = popen(cmd,"r");
if (fp == NULL) {
return 0;
}
size = fread(res,res_size,1,fp);
pclose(fp);
return size;
}
只写有效数量的元素。
int main(void) {
char cmd[500];
size_t size = fread_s(cmd,sizeof(cmd),"ls -lh i*");
// puts(cmd);
fwrite(cmd, size, 1, stdout);
FILE *fp=fopen("opfile","a+");
if(fp==NULL) {
return -1; // Add value to return
}
fwrite(cmd, size, 1, fp);
fclose(fp); // add fclose
}
答案 2 :(得分:1)
在标准输出中写入时,使用puts
编写字符串。该字符串不会以空值终止,但puts
很有可能在垃圾字符中包含空字符。可能会打印一些垃圾,但不是全部,因为可以吸引零。
(这个问题非常像那个问题,只是看到了:C Language: popen() with fread()?)
当您写入文件时,您将获得整个500个字符,包括垃圾字符(500个字符)
要获得相同的行为(但仍有一些可能的垃圾):
fwrite(cmd,strlen(cmd),1,fp);
或
fputs(cmd,fp);
但是在读取popen
的输出后,您必须为null终止字符串。