popen,argc,argv, cprintf, snprintf,strcmp,write,read,strspn,strcspn, r囧r小猫 2022-08-10 05:00 114阅读 0赞 **(转)** # **popen** # 简单说一下popen()函数 **函数定义** #include <stdio.h> FILE * popen(const char *command , const char *type ); int pclose(FILE *stream); ### 函数说明 ### popen()函数通过创建一个管道,调用fork()产生一个子进程,执行一个shell以运行命令来开启一个进程。这个管道必须由pclose()函数关闭,而不是fclose()函数。pclose()函数关闭标准I/O流,等待命令执行结束,然后返回shell的终止状态。如果shell不能被执行,则pclose()返回的终止状态与shell已执行exit一样。 type参数只能是读或者写中的一种,得到的返回值(标准I/O流)也具有和type相应的只读或只写类型。如果type是"r"则文件指针连接到command的标准输出;如果type是"w"则文件指针连接到command的标准输入。 command参数是一个指向以NULL结束的shell命令字符串的指针。这行命令将被传到bin/sh并使用-c标志,shell将执行这个命令。 popen()的返回值是个标准I/O流,必须由pclose来终止。前面提到这个流是单向的(只能用于读或写)。向这个流写内容相当于写入该命令的标准输入,命令的标准输出和调用popen()的进程相同;与之相反的,从流中读数据相当于读取命令的标准输出,命令的标准输入和调用popen()的进程相同。 返回值 如果调用fork()或pipe()失败,或者不能分配内存将返回NULL,否则返回标准I/O流。popen()没有为内存分配失败设置errno值。如果调用fork()或pipe()时出现错误,errno被设为相应的错误类型。如果type参数不合法,errno将返回EINVAL。 附上一个例子: //execute shell command //执行一个shell命令,输出结果逐行存储在resvec中,并返回行数 int32_t myexec(const char *cmd, vector<string> &resvec) { resvec.clear(); FILE *pp = popen(cmd, "r"); //建立管道 if (!pp) { return -1; } char tmp[1024]; //设置一个合适的长度,以存储每一行输出 while (fgets(tmp, sizeof(tmp), pp) != NULL) { if (tmp[strlen(tmp) - 1] == '\n') { tmp[strlen(tmp) - 1] = '\0'; //去除换行符 } resvec.push_back(tmp); } pclose(pp); //关闭管道 return resvec.size(); } \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* FILE *pp; if((pp=popen("nvram get bootimg", "r"))!=NULL) { fgets(bootimg, sizeof(bootimg), pp); boot_img=atoi(bootimg); } pclose(pp); # **argc,argv** 用[命令行][Link 1]编译程序时有用 # 主函数main中变量(int argc,char \*argv\[ \])的含义 有些 [编译器][Link 2]允许将main()的返回类型声明为void,这已不再是合法的C++ main(int argc, char \*argv\[ \], char \*\*env)才是 [UNIX][]和 [Linux][]中的标准写法。 argc: 整数,用来统计你运行程序时送给 [main函数][main]的 [命令行参数][Link 3]的个数 \* argv\[ \]: 字符串 [数组][Link 4],用来存放指向你的字符串参数的 [指针数组][Link 5],每一个元素指向一个参数 argv\[0\] 指向程序运行的全路径名 argv\[1\] 指向在DOS命令行中执行程序名后的第一个字符串 argv\[2\] 指向执行程序名后的第二个字符串 # **cprintf** # int cprintf(const char \*format\[, argument, ...\]); 功 能: 送格式化输出至屏幕 头文件: conio.h 说 明: 非ANSI C标准 cprintf与printf的区别如下: 1.cprintf函数用于向当前窗口输出数据,比如你用window函数定义一个窗口 window(20,10,60,20),那么当你调用cprintf函数时,cprintf的输出就是相对于20,10, 60,20这个窗口,当输出的字符串长度大于当前窗口长度时,会在当前窗口自动换行。 默认方式下,当前窗口为整个屏幕,即:0,0,79,25 2.cprintf函数可以配合setcolor,setbkcolor等函数使用,而调用printf函数时会忽略这些 函数执行的结果。 比如执行: setcolor(RED); cprintf("Hello world"); printf("Hello"); 将会在屏幕上显示红色字符串:Hello world 和白色字符串(因为setcolor函数对printf函数不起作用):Hello 楼上讲的都不完全对。 1:cprintf()并不将\\n解释成\\r\\n(即回车换行),它只是换行,没有回车; 2:cprintf()直接向当前文本窗口输出。 在原来的C语言中,cprintf中的c代表console,就是控制台.(conio.h中的con也是这个意思)到了windows也继承了这个渊源. 按照设计者本来的意图,printf是标准输出,就是指可以完全不知道你输出的对象,只是以标准的文本流方式输出.cprintf是与终端相关的,要用到一些系统平台,硬件设备相关的特性,所以可以有颜色等很多东西可供选择,同时也削弱了移植性所以cprintf是非标准的. 比如\\n 和\\n\\r在printf和cprintf当中都是另起新行的作用,但是在文本流中只需要输出\\n这个标准控制命令就可以起到行数加一同时列数置零的作用(如果输出被导向到屏幕).但是在控制台方式下,由于直接面对的是屏幕,那么这个命令被拆成两个动作:1)行数加1,即光标下移一格.2)列数置零,即光标回到同一行的最左端.而这两个动作在标准方式下是没有意义的,因为输出的对象不一定是屏幕那么"光标位置"也是不存在的了. # **snprintf** # int snprintf(char \*restrict buf, size\_t n, const char \* restrict format, ...); 函数说明:最多从源串中拷贝n-1个字符到目标串中,然后再在后面加一个0。所以如果目标串的大小为n 的话,将不会溢出。 函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。 Result1(推荐的用法) \#include <stdio.h> \#include <stdlib.h> int main() \{ char str\[10\]=\{0,\}; snprintf( str, sizeof(str ), "0123456789012345678"); printf("str=%s/n", str); return 0; \} root\] /root/lindatest $ ./test str=012345678 补充一下,snprintf的返回值是欲写入的字符串长度,而不是实际写入的字符串度。如: char test\[8\]; int ret = snprintf(test,5,"1234567890"); printf("%d|%s/n",ret,test); 运行结果为: 10|1234 sprintf函数返回的是 实际输出 到字符串缓冲中的字符个数,包括null结束符。 而snprintf函数返回的是 应该输出 到字符串缓冲的字符个数,所以snprintf的 返回值可能大于给定的可用缓冲大小以及最终得到 的字符串长度。 \------------------------------------------------------------------------------------------------- char a\[20\]; i = snprintf(a, 9, "%012d", 12345); printf("i = %d, a = %s", i, a); 输出为:i = 12, a = 000000012345 \---------------------------------- c语言中%2d 结果十进制,长度为2 ,右对齐,不够补空格,多了以实际长度输出 比如结果是1,输出: (空格)1 结果为123(长度大于等于2):输出:123 补充: %-2d 左对齐,其余同上 %04d,输出4位(十进制),不足在前面补0,如 123-》0123 # **strcmp()** # 用来比较字符串(区分大小写),其原型为: int strcmp(const char \*s1, const char \*s2); 【参数】 s1, s2 为需要比较的两个字符串。 字符串大小的比较是以ASCII 码表上的顺序来决定,此顺序亦为字符的值。strcmp()首先将s1 第一个字符值减去s2 第一个字符值,若差值为0 则再继续比较下个字符,若差值不为0 则将差值返回。例如字符串"Ac"和"ba"比较则会返回字符"A"(65)和'b'(98)的差值(-33)。 【返回值】 若参数s1 和s2 字符串相同则返回0。s1 若大于s2 则返回大于0 的值。s1 若小于s2 则返回小于0 的值。 # **write()** # 相关函数:open, read, fcntl, close, lseek, sync, fsync, fwrite 头文件:\#include <unistd.h> 定义函数:ssize\_t write (int fd, const void \* buf, size\_t count); 函数说明:write()会把参数buf 所指的内存写入count 个字节到参数fd 所指的文件内. 当然, 文件读写位置也会随之移动. write函数将buf中的nbytes字节内容写入文件描述符fd. 返回值:如果顺利write()会返回实际写入的字节数. 当有错误发生时则返回-1, 错误代码存入errno 中. 错误代码: EINTR 此调用被信号所中断. EAGAIN 当使用不可阻断I/O 时 (O\_NONBLOCK), 若无数据可读取则返回此值. EADF 参数fd 非有效的文件描述词, 或该文件已关闭. # **read()** # 相关函数:readdir, write, fcntl, close, lseek, readlink, fread 头文件:\#include <unistd.h> 定义函数:ssize\_t read(int fd, void \* buf, size\_t count); 函数说明:read()会把参数fd 所指的文件传送count 个字节到buf 指针所指的内存中. 若参数count 为0, 则read()不会有作用并返回0. 返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动. read函数是负责从fd中读取内容到buf里 附加说明: 如果顺利 read()会返回实际读到的字节数, 最好能将返回值与参数count 作比较, 若返回的字节数比要求读取的字节数少, 则有可能读到了文件尾、从管道(pipe)或终端机读read()被信号中断了读取动作. 当有错误发生时则返回-1, 错误代码存入errno 中, 而文件读写位置则无法预期. 错误代码: EINTR 此调用被信号所中断. EAGAIN 当使用不可阻断I/O 时(O\_NONBLOCK), 若无数据可读取则返回此值. EBADF 参数fd 非有效的文件描述词, 或该文件已关闭. # ** strspn** # (返回字符串中第一个不在指定字符串中出现的字符下标) \#include <string.h> 定义函数: size\_t strspn (const char \*s,const char \* accept); 函数说明 strspn()从参数s 字符串的开头计算连续的字符,而这些字符都完全是accept 所指字符串中的字符。简单的说,若strspn()返回的数值为n,则代表字符串s 开头连续有n 个字符都是属于字符串accept内的字符。 返回值 返回字符串s开头连续包含字符串accept内的字符数目。 ![Center][] # ** strcspn** # 原型:size\_t strcspn(const char \*s, const char \* reject); 相关头文件:string.h 函数说明:strcspn()从参数s 字符串的开头计算连续的字符, 而这些字符都完全不在参数reject 所指的字符串中. 简单地说, 若strcspn()返回的数值为n, 则代表字符串s 开头连续有n 个字符都不含字符串reject 内的字符. 返回值:返回字符串s 开头连续不含字符串reject 内的字符数目 ![Image 1][] ![Center 1][] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* [Link 1]: http://baike.baidu.com/view/1411569.htm [Link 2]: http://baike.baidu.com/view/487018.htm [UNIX]: http://baike.baidu.com/view/8095.htm [Linux]: http://baike.baidu.com/view/1634.htm [main]: http://baike.baidu.com/view/379148.htm [Link 3]: http://baike.baidu.com/view/1646320.htm [Link 4]: http://baike.baidu.com/view/209670.htm [Link 5]: http://baike.baidu.com/view/2072881.htm [Center]: /images/20220731/0d18858b86a94bb0844212192fd8a10a.png [Image 1]: [Center 1]: /images/20220731/2e6ed31993ec4ded9307e6b8d6c972ec.png
相关 popen,argc,argv, cprintf, snprintf,strcmp,write,read,strspn,strcspn, (转) popen 简单说一下popen()函数 函数定义 include <stdio.h> FILE popen(cons r囧r小猫/ 2022年08月10日 05:00/ 0 赞/ 115 阅读
相关 MIT OS lab3--小结续 系统调用与用户接口 (cprintf..) MIT OS lab3--小结续 系统调用与用户接口 (cprintf..) 2010-01-30 16:31 <table style="table-layout:fix 水深无声/ 2022年06月05日 07:54/ 0 赞/ 168 阅读
相关 cprintf define cprintf(fmt, args...) do { \ FILE fp = fopen("/dev/console", "w"); \ 分手后的思念是犯贱/ 2022年05月25日 04:49/ 0 赞/ 28 阅读
还没有评论,来说两句吧...