简单说一下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 用命令行编译程序时有用
主函数main中变量(int argc,char *argv[ ])的含义
有些 编译器允许将main()的返回类型声明为void,这已不再是合法的C++
main(int argc, char *argv[ ], char **env)才是 UNIX和 Linux中的标准写法。
argc: 整数,用来统计你运行程序时送给 main函数的 命令行参数的个数
* argv[ ]: 字符串 数组,用来存放指向你的字符串参数的 指针数组,每一个元素指向一个参数
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内的字符数目。
strcspn
原型:size_t strcspn(const char *s, const char * reject);
相关头文件:string.h
函数说明:strcspn()从参数s 字符串的开头计算连续的字符, 而这些字符都完全不在参数reject 所指的字符串中. 简单地说, 若strcspn()返回的数值为n, 则代表字符串s 开头连续有n 个字符都不含字符串reject 内的字符.
返回值:返回字符串s 开头连续不含字符串reject 内的字符数目
*****************************************************************
*****************************************************************