C 语言:popen() 和 fread()?
我已经在这个问题上坚持了几天了,这真的很令人沮丧。
我使用 popen()
调用命令行进程并获取其输出并将其存储在 C 字符串中。我正在使用 fgets()
但似乎在新行后中断,所以我使用 fread()
。唯一的问题是返回的 C 字符串有时会很混乱。
这是我的代码:
const char *cmd = "date";//This the shell command
char buf[BUFSIZ];//Output of the command
FILE *ptr;
int c;
if ((ptr = popen(cmd, "r")) != NULL)
while(fread(buf, sizeof(buf),1, ptr))
while ((c = getchar()) != EOF)
printf("output = %s", buf);
(void) pclose(ptr);
最终的 C 字符串有时包含不应该存在的奇怪字符,或者有时甚至没有可用的字符串。有人可以帮忙吗? ):
编辑:这是我在使用 fgets() 时所做的事情。 Shell 命令可以是任何输出文本的命令。不仅仅是“约会”。
if ((ptr = popen(cmd, "r")) != NULL)
while (fgets(buf, BUFSIZ, ptr) != NULL)
printf("output = % s", buf);
(void) pclose(ptr);
I've been stuck on this for a few days and it's getting really frustrating.
I'm using popen()
to call a command line process and get its output and store it in a C string. I was using fgets()
but it seems that breaks after a new line, so I'm using fread()
. The only problem is that the returned C string is sometimes messed up.
Here's my code:
const char *cmd = "date";//This the shell command
char buf[BUFSIZ];//Output of the command
FILE *ptr;
int c;
if ((ptr = popen(cmd, "r")) != NULL)
while(fread(buf, sizeof(buf),1, ptr))
while ((c = getchar()) != EOF)
printf("output = %s", buf);
(void) pclose(ptr);
The final C string sometimes has weird characters in it that shouldn't be there, or sometimes no string is even available. Can anybody please help? ):
Edit: Here is what I was doing when using fgets() The Shell command can be anything that outputs text though. Not just "date."
if ((ptr = popen(cmd, "r")) != NULL)
while (fgets(buf, BUFSIZ, ptr) != NULL)
printf("output = %s", buf);
(void) pclose(ptr);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
fread
不会在读取的内容后插入 NUL 终止符。您需要检查返回值以了解读取了多少内容,并且仅打印该内容。如果您使用fread
读取数据,则通常需要使用fwrite
写入数据,顺序如下:fread
doesn't insert a NUL terminator after what it reads. You need to check the return value to know how much it read, and only print that much. If you read withfread
, you typically want to write the data withfwrite
, something on this order:嗯,
fgets
是正确的方法。我认为
fgets
不适合你的原因是你做错了什么。现在,这就是为什么我认为您当前的代码遇到了麻烦:
fread
getchar
读取并丢弃NUL
终止符正确处理这一点,一切都会更好:
fread
可能会合法地读取比您告诉它的更少的内容。Well,
fgets
is the right way to do it.I think the reason
fgets
wasn't working for you is that you were doing something wrong.Now, here's why I think you are running into trouble with your current code:
fread
actually returnedgetchar
and discarding stuffNUL
terminator in the bufferGet this right and it will all be better:
fread
might legally read less than you told it to.下面是使用
fread
通过popen
进行进程输出的正确方法:如您所见,首要问题是正确处理 null 终止。
fread
的两个size参数也很重要,你必须让它一个字符一个字符地读取(意味着fread
的第二个参数必须是1 )。请注意,在
popen
的情况下,如果进程退出且没有给出任何输出,fread
将仅返回 0。如果进程需要很长时间才能打印任何内容,它不会返回 0。如果输出大于
BUFSIZ
,您可以用while
循环包装fread
。Below is the correct way to use
fread
for process output withpopen
:As you can see, the primary problem is to correctly deal with null termination. The two size parameter of
fread
is also important, you have to let it read character by character (means that second parameter offread
must be 1).Note that in the case of
popen
,fread
will only return 0 if the process has exited without giving any output. It will not return 0 if it takes a long time for the process to print anything.If the output is larger than
BUFSIZ
, you can wrapfread
with awhile
loop.date
的输出不包含正确终止字符串所需的'\0'
(NUL) 字符。跟踪自己读取并放入 NUL 的字符数。虽然实际上,您应该使用
fgets
、getline
或类似的面向文本的函数,用于从date
等程序中读取。getline
特别简单(而且安全,因为它为您做了一些内存管理):The output from
date
doesn't include the'\0'
(NUL) character you need to properly terminate the string. Keep track of the number of characters read and put in the NUL yourself.Though really, you should be using
fgets
,getline
or similar text-oriented functions to read from a program such asdate
.getline
is especially easy (and safe since it does some memory management for you):