项目场景:
例如:在交换机抓包实例中,需要将抓包文件通过tftp传送到本地,但如果文件不存在,或者被覆盖,使用system(),会报tftp标准错误提示,时常会有乱码的存在,故不符合产品设计要求。
c语言中的poepn 如何捕获错误输出
在C语言中,可以使用标准库中的popen函数来执行外部命令并捕获其标准输出,但要捕获错误输出(标准错误流),需要执行一些额外的步骤。一种常见的方法是将标准错误流重新定向到与标准输出流相同的地方,然后一起捕获。具体实现如下:
//变量定义
s8 str[128] = {};
u32 status;
FILE* fp;
char buffer[128];
char* ret = NULL;
/*上传文件*/
snprintf(str, 128, "tftp -pl %s %u.%u.%u.%u 2>&1", *filename_ptr, (*ip_ptr>>24)&0xFF,(*ip_ptr>>16)&0xFF,(*ip_ptr>>8)&0xFF,(*ip_ptr)&0xFF);
/* 将标准出错重定向到标准输出,避免出错信息直接打印到串口 */
fp = popen(str, "r");
if(fp == NULL)
{
perror("popen");
exit(EXIT_FAILURE);
}
while(fgets(buffer, sizeof(buffer), fp) != NULL)
{
ret = strstr(buffer,"error"); //是否有报错
if(ret)
{
printf("ERROR:File download failed!\r\n");
}
else
{
printf("File download successful!\r\n");
}
}
status = pclose(fp);
if(status == -1)
{
perror("pclose");
exit(EXIT_FAILURE);
}
代码解释:
我们使用popen
来执行命令tftp,并将标准错误流(2)重新定向到标准输出流(1)。这使得标准错误流的内容也被捕获到fp文件指针中。然后,我们使用“fgets来逐行读取“fp"中的输出,并将其打印出来。
最后,我们使用pclose
来关闭fp,并检查命令的返回值(退出状态)。如果pclose
返回-1,则表示有错误,我们使用perror
来输出错误信息。
请注意,上述示例中使用了系统依赖的shell特性
(“2>&1’)来重新定向标准错误流。如果要执行的命令没有使用shell,则可能需要使用不同的方法来重定向标准错误流。
其他函数详解
(1)fgets
fgets 函数功能为从指定的流中读取数据,每次读取一行。其原型为:
#include <stdio.h>
#include <stdlib.h>
/*
*描述:从指定的流 stream 读取一行,并把它存储在str所指向的字符串内。当读取(n-1)个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止
*
*参数:
- [in] str: 缓冲区,用来存放要读取的字符串;
- [in] n: 要读取的最大字符数(包括最后的空字符),通常是使用以 str 传递的数组长度;
- [in] stream:文件指针句柄;
*返回值:如果成功,该函数返回读取到的数据,内容和 str 缓冲区数据一样。如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。如果发生错误,返回一个空指针
*/
char *fgets(char *str, int n, FILE *stream);
如果文件中的该行,不足 n-1 个字符,则读完该行就结束;
如若该行(包括最后一个换行符)的字符数超过 n-1 ,则 fgets 只返回一个不完整的行,但是,缓冲区总是以 NULL 字符结尾,对 fgets 的下一次调用会继续读该行;
函数成功将返回 stream,失败或读到文件结尾返回 NULL 。因此不能直接通过 fgets 的返回值来判断函数是否是出错而终止的,应该借助 feof 函数或者 ferror 函数来判断;
(2)strstr
定义:strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。
该函数返回字符串的其余部分(从匹配点)。
注意:strstr(str1,str2) 此时千万要记住,这是在判断str2是否是str1的子串!!
比如:
char str2 = “cdef”;
char str1 = “abcdefgh”;
则通过函数,将返回
strstr(str1,str2) = cdefgh;
如果str1不包含有str2。
char str2 = “cxef”;
char str1 = “abcdefgh”;
则通过函数,将返回
strstr(str1,str2) = NULL;