您正在查看: C 分类下的文章

linuxC进程操作篇

atexit(设置程序正常结束前调用的函数)

相关函数 _exit,exit,on_exit
表头文件 #include<stdlib.h>
定义函数 int atexit (void (*function)(void));
函数说明 atexit()用来设置一个程序正常结束前调用的函数。当程序通过调用exit()或从main中返回时,参数function所指定的函数会先被调用,然后才真正由exit()结束程序。
返回值 如果执行成功则返回0,否则返回-1,失败原因存于errno中。

 

范例**

#include<stdlib.h>
void my_exit(void)
{
printf(“before exit () !\n”);
}
main()
{
atexit (my_exit);
exit(0);
}
执行 before exit()!

execl(执行文件)

相关函数 fork,execle,execlp,execv,execve,execvp
表头文件 #include<unistd.h>
定义函数 int execl(const char * path,const char * arg,....);
函数说明 execl()用来执行参数path字符串所代表的文件路径,接下来的参数代表执行该文件时传递过去的argv(0)、argv[1]……,最后一个参数必须用空指针(NULL)作结束。
返回值 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。

 

范例**

#include<unistd.h>
main()
{
execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char * )
0);
}
执行
/*执行/bin/ls -al /etc/passwd */
-rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
 

execlp(从PATH 环境变量中查找文件并执行)

相关函数 fork,execl,execle,execv,execve,execvp
表头文件 #include<unistd.h>
定义函数 int execlp(const char * file,const char * arg,……);
函数说明 execlp()会从PATH     环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。
返回值 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
错误代码 参考execve()。

 

范例**

/* 执行ls -al /etc/passwd execlp()会依PATH 变量中的/bin找到/bin/ls */
#include<unistd.h>
main()
{
execlp(“ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);
}
执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd

execv(执行文件)

相关函数 fork,execl,execle,execlp,execve,execvp
表头文件 #include<unistd.h>
定义函数 int execv (const char * path, char * const argv[ ]);
函数说明 execv()用来执行参数path字符串所代表的文件路径,与execl()不同的地方在于execve()只需两个参数,第二个参数利用数组指针来传递给执行文件。
返回值 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
错误代码 请参考execve()。

 

范例**

/* 执行/bin/ls -al /etc/passwd */
#include<unistd.h>
main()
{
char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char*) }};
execv(“/bin/ls”,argv);
}
执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd

execve(执行文件)

相关函数 fork,execl,execle,execlp,execv,execvp
表头文件 #include<unistd.h>
定义函数 int execve(const char * filename,char * const argv[ ],char
* const envp[ ]);
函数说明 execve()用来执行参数filename字符串所代表的文件路径,第二个
参数系利用数组指针来传递给执行文件,最后一个参数则为传递给
执行文件的新环境变量数组。
返回值 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因
存于errno 中。
错误代码 EACCES
1. 欲执行的文件不具有用户可执行的权限。
2. 欲执行的文件所属的文件系统是以noexec 方式挂上。
3.欲执行的文件或script翻译器非一般文件。
EPERM
1.进程处于被追踪模式,执行者并不具有root权限,欲执行的文件
具有SUID 或SGID 位。
2.欲执行的文件所属的文件系统是以nosuid方式挂上,欲执行的文
件具有SUID 或SGID 位元,但执行者并不具有root权限。
E2BIG 参数数组过大
ENOEXEC 无法判断欲执行文件的执行文件格式,有可能是格式错误
或无法在此平台执行。
EFAULT 参数filename所指的字符串地址超出可存取空间范围。
ENAMETOOLONG 参数filename所指的字符串太长。
ENOENT 参数filename字符串所指定的文件不存在。
ENOMEM 核心内存不足
ENOTDIR 参数filename字符串所包含的目录路径并非有效目录
EACCES 参数filename字符串所包含的目录路径无法存取,权限不足
ELOOP 过多的符号连接
ETXTBUSY 欲执行的文件已被其他进程打开而且正把数据写入该文件
中
EIO I/O 存取错误
ENFILE 已达到系统所允许的打开文件总数。
EMFILE 已达到系统所允许单一进程所能打开的文件总数。
EINVAL 欲执行文件的ELF执行格式不只一个PT_INTERP节区
EISDIR ELF翻译器为一目录
ELIBBAD ELF翻译器有问题。

 

范例**

#include<unistd.h>
main()
{
char * argv[ ]={“ls”,”-al”,”/etc/passwd”,(char *)0};
char * envp[ ]={“PATH=/bin”,0}
execve(“/bin/ls”,argv,envp);
}
执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
 

execvp(执行文件)

相关函数 fork,execl,execle,execlp,execv,execve
表头文件 #include<unistd.h>
定义函数 int execvp(const char *file ,char * const argv []);
函数说明 execvp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。
返回值 如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。
错误代码 请参考execve()。
 

范例**

/*请与execlp()范例对照*/
#include<unistd.h>
main()
{
char * argv[ ] ={ “ls”,”-al”,”/etc/passwd”,0};
execvp(“ls”,argv);
}
执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd

exit(结束进程执行)

相关函数 exit,wait,abort
表头文件 #include<unistd.h>
定义函数 void _exit(int status);
函数说明 _exit()用来立刻结束目前进程的执行,并把参数status返回给父进程,并关闭未关闭的文件。此函数调用后不会返回,并且会传递SIGCHLD信号给父进程,父进程可以由wait函数取得子进程结束状态。
返回值
附加说明 _exit()不会处理标准I/O 缓冲区,如要更新缓冲区请使用exit()。

范例**

fprintf(格式化输出数据至文件)

相关函数 printf,fscanf,vfprintf
表头文件 #include<stdio.h>
定义函数 int fprintf(FILE * stream, const char * format,.......);
函数说明 fprintf()会根据参数format字符串来转换并格式化数据,然后将结果输出到参数stream指定的文件中,直到出现字符串结束('\0')为止。
返回值 关于参数format字符串的格式请参考printf()。成功则返回实际输出的字符数,失败则返回-1,错误原因存于errno中。

 

范例**

#include<stdio.h>
main()
{
int i = 150;
int j = -100;
double k = 3.14159;
fprintf(stdout,”%d %f %x \n”,j,k,i);
fprintf(stdout,”%2d %*d\n”,i,2,i);
}
执行 -100 3.141590 96
150 150

范例**

**#include<stdio.h>
main()
{
int i;
unsigned int j;
char s[5];
fscanf(stdin,”%d %x %5[a-z] %*s %f”,&amp;i,&amp;j,s,s);
printf(“%d %d %s \n”,i,j,s);
}
执行 10 0x1b aaaaaaaaa bbbbbbbbbb /*从键盘输入*/
10 27 aaaaa
 

getpgid(取得进程组识别码)

相关函数 setpgid,setpgrp,getpgrp
表头文件 #include<unistd.h>
定义函数 pid_t getpgid( pid_t pid);
函数说明 getpgid()用来取得参数pid 指定进程所属的组识别码。如果参数pid为0,则会取得目前进程的组识别码。
返回值 执行成功则返回组识别码,如果有错误则返回-1,错误原因存于errno中。
错误代码 ESRCH 找不到符合参数pid 指定的进程。

 

范例**

/*取得init 进程(pid=1)的组识别码*/
#include<unistd.h>
mian()
{
printf(“init gid = %d\n”,getpgid(1));
}
执行 init gid = 0
 

getpgrp(取得进程组识别码)

相关函数 setpgid,getpgid,getpgrp
表头文件 #include<unistd.h>
定义函数 pid_t getpgrp(void);
函数说明 getpgrp()用来取得目前进程所属的组识别码。此函数相当于调用
getpgid(0);
返回值 返回目前进程所属的组识别码。
 

范例**

#include<unistd.h>
main()
{
printf(“my gid =%d\n”,getpgrp());
}
执行 my gid =29546

getpid(取得进程识别码)

相关函数 fork,kill,getpid
表头文件 #include<unistd.h>
定义函数 pid_t getpid(void);
函数说明 getpid()用来取得目前进程的进程识别码,许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。
返回值 目前进程的进程识别码

 

范例**

#include<unistd.h>
main()
{
printf(“pid=%d\n”,getpid());
}
执行 pid=1494 /*每次执行结果都不一定相同*/
 

getppid(取得父进程的进程识别码)

相关函数 fork,kill,getpid
表头文件 #include<unistd.h>
定义函数 pid_t getppid(void);
函数说明 getppid()用来取得目前进程的父进程识别码。
返回值 目前进程的父进程识别码。

 

范例**

#include<unistd.h>
main()
{
printf(“My parent ‘pid =%d\n”,getppid());
}
执行 My parent pid =463
 

getpriority(取得程序进程执行优先权)

相关函数 setpriority,nice
表头文件 #include<sys/time.h>
#include<sys/resource.h>
定义函数 int getpriority(int which,int who);
函数说明 getpriority()可用来取得进程、进程组和用户的进程执行优先权。
参数 which有三种数值,参数who 则依which值有不同定义
which who 代表的意义
PRIO_PROCESS who 为进程识别码
PRIO_PGRP who 为进程的组识别码
PRIO_USER who 为用户识别码
此函数返回的数值介于-20 至20之间,代表进程执行优先权,数值
越低代表有较高的优先次序,执行会较频繁。
返回值 返回进程执行优先权,如有错误发生返回值则为-1 且错误原因存于errno。
附加说明 由于返回值有可能是-1,因此要同时检查errno是否存有错误原因。
最好在调用次函数前先清除errno变量。
错误代码 ESRCH 参数which或who 可能有错,而找不到符合的进程。EINVAL参数which 值错误。
 

范例**

nice(改变进程优先顺序)

相关函数 setpriority,getpriority
表头文件 #include<unistd.h>
定义函数 int nice(int inc);
函数说明 nice()用来改变进程的进程执行优先顺序。参数inc数值越大则优先顺序排在越后面,即表示进程执行会越慢。只有超级用户才能使用负的inc   值,代表优先顺序排在前面,进程执行会较快。
返回值 如果执行成功则返回0,否则返回-1,失败原因存于errno中。
错误代码 EPERM 一般用户企图转用负的参数inc值改变进程优先顺序。

范例**

on_exit(设置程序正常结束前调用的函数)

相关函数 _exit,atexit,exit
表头文件 #include<stdlib.h>
定义函数 int on_exit(void (* function)(int, void*),void *arg);
函数说明 on_exit()用来设置一个程序正常结束前调用的函数。当程序通过调用exit()或从main中返回时,参数function所指定的函数会先被调用,然后才真正由exit()结束程序。参数arg指针会传给参数function函数,详细情况请见范例。
返回值 如果执行成功则返回0,否则返回-1,失败原因存于errno中。
附加说明

 

范例**

范例 #include<stdlib.h>
void my_exit(int status,void *arg)
{
printf(“before exit()!\n”);
printf(“exit (%d)\n”,status);
printf(“arg = %s\n”,(char*)arg);
}
main()
{
char * str=”test”;
on_exit(my_exit,(void *)str);
exit(1234);
}
执行 before exit()!
exit (1234)
arg = test

printf(格式化输出数据)

相关函数 scanf,snprintf
表头文件 #include<stdio.h>
定义函数 int printf(const char * format,.............);
函数说明
printf()会根据参数format字符串来转换并格式化数据,然后将结
果写出到标准输出设备,直到出现字符串结束('\0')为止。参数
format字符串可包含下列三种字符类型
1.一般文本,伴随直接输出。
2.ASCII控制字符,如\t、\n等。
3.格式转换字符。
格式转换为一个百分比符号(%)及其后的格式字符所组成。一般而
言,每个%符号在其后都必需有一printf()的参数与之相呼应(只
有当%%转换字符出现时会直接输出%字符),而欲输出的数据类
型必须与其相对应的转换字符类型相同。
Printf()格式转换的一般形式如下
%(flags)(width)(.prec)type
以中括号括起来的参数为选择性参数,而%与type则是必要的。底
下先介绍type的几种形式整数
%d 整数的参数会被转成一有符号的十进制数字
%u 整数的参数会被转成一无符号的十进制数字
%o 整数的参数会被转成一无符号的八进制数字
%x 整数的参数会被转成一无符号的十六进制数字,并以小写
abcdef表示
%X 整数的参数会被转成一无符号的十六进制数字,并以大写
ABCDEF表示浮点型数
%f double 型的参数会被转成十进制数字,并取到小数点以下六
位,四舍五入。
%e double型的参数以指数形式打印,有一个数字会在小数点前,
六位数字在小数点后,而在指数部分会以小写的e来表示。
%E 与%e作用相同,唯一区别是指数部分将以大写的E 来表示。
%g double 型的参数会自动选择以%f 或%e 的格式来打印,其标
准是根据欲打印的数值及所设置的有效位数来决定。
%G 与%g 作用相同,唯一区别在以指数形态打印时会选择%E 格
式。
字符及字符串
%c 整型数的参数会被转成unsigned char型打印出。
%s 指向字符串的参数会被逐字输出,直到出现NULL字符为止
%p 如果是参数是“void *”型指针则使用十六进制格式显示。
prec 有几种情况
1. 正整数的最小位数。
2.在浮点型数中代表小数位数
3.在%g 格式代表有效位数的最大值。
4.在%s格式代表字符串的最大长度。
5.若为×符号则代表下个参数值为最大长度。
width为参数的最小长度,若此栏并非数值,而是*符号,则表示以
下一个参数当做参数长度。
flags 有下列几种情况
#NAME?
+ 一般在打印负数时,printf()会加印一个负号,整数则不加任
何负号。此旗标会使得在打印正数前多一个正号(+)。
# 此旗标会根据其后转换字符的不同而有不同含义。当在类型为o
之前(如%#o),则会在打印八进制数值前多印一个o。
而在类型为x 之前(%#x)则会在打印十六进制数前多印’0x’,
在型态为e、E、f、g或G 之前则会强迫数值打印小数点。在类型为g
或G之前时则同时保留小数点及小数位数末尾的零。
0 当有指定参数时,无数字的参数将补上0。默认是关闭此旗标,所
以一般会打印出空白字符。
返回值 成功则返回实际输出的字符数,失败则返回-1,错误原因存于errno中。

 

范例**

#include<stdio.h>
main()
{
int i = 150;
int j = -100;
double k = 3.14159;
printf(“%d %f %x\n”,j,k,i);
printf(“%2d %*d\n”,i,2,i); /*参数2 会代入格式*中,而与%2d
同意义*/
}
执行 -100 3.14159 96
150 150

范例**

**#include <stdio.h>
main()
{
int i;
unsigned int j;
char s[5];
scanf(“%d %x %5[a-z] %*s %f”,&amp;i,&amp;j,s,s);
printf(“%d %d %s\n”,i,j,s);
}
执行 10 0x1b aaaaaaaaaa bbbbbbbbbb
10 27 aaaaa

setpgid(设置进程组识别码)

相关函数 getpgid,setpgrp,getpgrp
表头文件 #include<unistd.h>
定义函数 int setpgid(pid_t pid,pid_t pgid);
函数说明 setpgid()将参数pid 指定进程所属的组识别码设为参数pgid 指定的组识别码。如果参数pid 为0,则会用来设置目前进程的组识别码,如果参数pgid为0,则会以目前进程的进程识别码来取代。
返回值 执行成功则返回组识别码,如果有错误则返回-1,错误原因存于errno中。
错误代码 EINVAL 参数pgid小于0。
EPERM 进程权限不足,无法完成调用。
ESRCH 找不到符合参数pid指定的进程。
 

范例**

setpgrp(设置进程组识别码)

相关函数 getpgid,setpgid,getpgrp
表头文件 #include<unistd.h>
定义函数 int setpgrp(void);
函数说明 setpgrp()将目前进程所属的组识别码设为目前进程的进程识别码。
此函数相当于调用setpgid(0,0)。
返回值 执行成功则返回组识别码,如果有错误则返回-1,错误原因存于errno中。

范例**

setpriority(设置程序进程执行优先权)

相关函数 getpriority,nice
表头文件 #include<sys/time.h>
#include<sys/resource.h>
定义函数 int setpriority(int which,int who, int prio);
函数说明 setpriority()可用来设置进程、进程组和用户的进程执行优先权。
参数which有三种数值,参数who 则依which值有不同定义
which who 代表的意义
PRIO_PROCESS who为进程识别码
PRIO_PGRP who 为进程的组识别码
PRIO_USER who为用户识别码
参数prio介于-20 至20 之间。代表进程执行优先权,数值越低代表
有较高的优先次序,执行会较频繁。此优先权默认是0,而只有超级
用户(root)允许降低此值。
返回值 执行成功则返回0,如果有错误发生返回值则为-1,错误原因存于errno。
ESRCH 参数which或who 可能有错,而找不到符合的进程
EINVAL 参数which值错误。
EPERM 权限不够,无法完成设置
EACCES 一般用户无法降低优先权

范例**

范例**

**main()
{
char * a=”This is string A!”;
char buf[80];
sprintf(buf,”>>> %s<<<\n”,a);
printf(“%s”.buf);
}
执行 >>>This is string A!<<<

sscanf(格式化字符串输入)

相关函数 scanf,fscanf
表头文件 #include<stdio.h>
定义函数 int sscanf (const char *str,const char * format,........);
函数说明 sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。
返回值 成功则返回参数数目,失败则返回-1,错误原因存于errno中。

 

范例**

#include<stdio.h>
main()
{
int i;
unsigned int j;
char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”;
char s[5];
sscanf(input,”%d %x %5[a-z] %*s %f”,&amp;i,&amp;j,s,s);
printf(“%d %d %s\n”,i,j,s);
}
执行 10 27 aaaaa

system(执行shell 命令)

相关函数 fork,execve,waitpid,popen
表头文件 #include<stdlib.h>
定义函数 int system(const char * string);
函数说明 system()会调用fork()产生子进程,由子进程来调用/bin/sh-c
string来执行参数string字符串所代表的命令,此命令执行完后随
即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时
搁置,SIGINT和SIGQUIT 信号则会被忽略。
返回值 如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-
1。若参数string为空指针(NULL),则返回非零值。如果system()调
用成功则最后会返回执行shell命令后的返回值,但是此返回值也有
可能为system()调用/bin/sh失败所返回的127,因此最好能再检查
errno 来确认执行成功。
附加说明 在编写具有SUID/SGID权限的程序时请勿使用system(),system()会
继承环境变量,通过环境变量可能会造成系统安全的问题。
 

范例**

#include<stdlib.h>
main()
{
system(“ls -al /etc/passwd /etc/shadow”);
}
执行 -rw-r--r-- 1 root root 705 Sep 3 13 :52 /etc/passwd
-r--------- 1 root root 572 Sep 2 15 :34 /etc/shadow

vfork(建立一个新的进程)

相关函数 wait,execve
表头文件 #include<unistd.h>
定义函数 pid_t vfork(void);
函数说明 vfork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。linux    使用copy-on-write(COW)技术,只有当其中一进程试图修改欲复制的空间时才会做真正的复制动作,由于这些继承的信息是复制而来,并非指相同的内存空间,因此子进程对这些变量的修改和父进程并不会同步。此外,子进程不会继承父进程的文件锁定和未处理的信号。注意,linux不保证子进程会比父进程先执行或晚执行,因此编写程序时要留意死锁或竞争条件的发生。
返回值 如果vfork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回0。如果vfork    失败则直接返回-1,失败原因存于errno中。
错误代码 EAGAIN 内存不足。ENOMEM 内存不足,无法配置核心所需的数据结构空间。
 

范例**

#include<unistd.h>
main()
{
if(vfork() = =0)
{
printf(“This is the child process\n”);
}else{
printf(“This is the parent process\n”);
}
}
执行 this is the parent process
this is the child process

vfprintf(格式化输出数据至文件)

相关函数 printf,fscanf,fprintf
表头文件 #include<stdio.h>
#include<stdarg.h>
定义函数 int vfprintf(FILE *stream,const char * format,va_list ap);
函数说明 vfprintf()会根据参数format字符串来转换并格式化数据,然后将结果输出到参数stream指定的文件中,直到出现字符串结束(’\0’)为止。关于参数format字符串的格式请参考printf()。
va_list用法请参考附录C或vprintf()范例。
返回值 成功则返回实际输出的字符数,失败则返回-1,错误原因存于errno中。
 

范例**

参考fprintf()及vprintf()。

范例**

**参考fscanf()及vprintf()。

vprintf(格式化输出数据)

相关函数 printf,vfprintf,vsprintf
表头文件 #include<stdio.h>
#include<stdarg.h>
定义函数 int vprintf(const char * format,va_list ap);
函数说明 vprintf()作用和printf()相同,参数format格式也相同。va_list为不定个数的参数列,用法及范例请参考附录C。
返回值 成功则返回实际输出的字符数,失败则返回-1,错误原因存于errno中。

 

范例**

#include<stdio.h>
#include<stdarg.h>
int my_printf( const char *format,……)
{
va_list ap;
int retval;
va_start(ap,format);
printf(“my_printf( ):”);
retval = vprintf(format,ap);
va_end(ap);
return retval;
}
main()
{
int i = 150,j = -100;
double k = 3.14159;
my_printf(“%d %f %x\n”,j,k,i);
my_printf(“%2d %*d\n”,i,2,i);
}
执行 my_printf() : -100 3.14159 96
my_printf() : 150 150

范例**

**请参考scanf()及vprintf()。

范例**

**请参考vprintf()及vsprintf()。

vsscanf(格式化字符串输入)

相关函数 vscanf,vfscanf
表头文件 #include<stdio.h>
定义函数 int vsscanf(const char * str,const char * format,va_listap);
函数说明 vsscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考附录C 或vprintf()范例。
返回值 成功则返回参数数目,失败则返回-1,错误原因存于errno中。
 

范例**

请参考sscanf()及vprintf()。

wait(等待子进程中断或结束)

相关函数 waitpid,fork
表头文件 #include<sys/types.h>
#include<sys/wait.h>
定义函数 pid_t wait (int * status);
函数说明    wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。子进程的结束状态值会由参数status   返回,而子进程的进程识别码也会一快返回。如果不在意结束状态值,则参数 status可以设成NULL。子进程的结束状态值请参考waitpid()。
返回值 如果执行成功则返回子进程识别码(PID),如果有错误发生则返回-1。失败原因存于errno中。
附加说明

 

范例**

#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
main()
{
pid_t pid;
int status,i;
if(fork()= =0){
printf(“This is the child process .pid =%d\n”,getpid());
exit(5);
}else{
sleep(1);
printf(“This is the parent process ,wait for child...\n”;
pid=wait(&amp;status);
i=WEXITSTATUS(status);
printf(“child’s pid =%d .exit status=^d\n”,pid,i);
}
}
执行 This is the child process.pid=1501
This is the parent process .wait for child...
child’s pid =1501,exit status =5

范例**

**参考wait()。

linuxC接口处理篇

accept(接受socket连线)

相关函数 socket,bind,listen,connect
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int accept(int s,struct sockaddr * addr,int * addrlen);
函数说明 accept()用来接受参数s的socket连线。参数s的socket必需先经bind()、listen()函数处理过,当有连线进来时accept()会返回一个新的socket处理代码,往后的数据传送与读取就是经由新的socket处理,而原来参数s的socket能继续使用accept()来接受新的连线要求。连线成功时,参数addr所指的结构会被系统填入远程主
机的地址数据,参数addrlen为scokaddr的结构长度。关于结构
sockaddr的定义请参考bind()。
返回值 成功则返回新的socket处理代码,失败返回-1,错误原因存于errno中。
错误代码 EBADF 参数s 非合法socket处理代码。
EFAULT 参数addr指针指向无法存取的内存空间。
ENOTSOCK 参数s为一文件描述词,非socket。
EOPNOTSUPP 指定的socket并非SOCK_STREAM。
EPERM 防火墙拒绝此连线。
ENOBUFS 系统的缓冲内存不足。
ENOMEM 核心内存不足。

 

范例**

参考listen()。

bind(对socket定位)

相关函数 socket,accept,connect,listen
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int bind(int sockfd,struct sockaddr * my_addr,int addrlen);
函数说明 bind()用来设置给参数sockfd的socket一个名称。此名称由参数my_addr指向一sockaddr结构,对于不同的socket  domain定义了一个通用的数据结构
struct sockaddr
{
unsigned short int sa_family;
char sa_data[14];
};
sa_family 为调用socket()时的domain参数,即AF_xxxx值。
sa_data 最多使用14个字符长度。
此sockaddr结构会因使用不同的socket domain而有不同结构定义,
例如使用AF_INET domain,其socketaddr结构定义便为
struct socketaddr_in
{
unsigned short int sin_family;
uint16_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
struct in_addr
{
uint32_t s_addr;
};
sin_family 即为sa_family
sin_port 为使用的port编号
sin_addr.s_addr 为IP 地址
sin_zero 未使用。
参数 addrlen为sockaddr的结构长度。
返回值 成功则返回0,失败返回-1,错误原因存于errno中。
错误代码 EBADF 参数sockfd 非合法socket处理代码。
EACCESS 权限不足
ENOTSOCK 参数sockfd为一文件描述词,非socket。
 

范例**

参考listen()

connect(建立socket连线)

相关函数 socket,bind,listen
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
函数说明 connect()用来将参数sockfd 的socket 连至参数serv_addr 指定的网络地址。结构sockaddr请参考bind()。参数addrlen为sockaddr的结构长度。
返回值 成功则返回0,失败返回-1,错误原因存于errno中。
错误代码 EBADF 参数sockfd 非合法socket处理代码
EFAULT 参数serv_addr指针指向无法存取的内存空间
ENOTSOCK 参数sockfd为一文件描述词,非socket。
EISCONN 参数sockfd的socket已是连线状态
ECONNREFUSED 连线要求被server端拒绝。
ETIMEDOUT 企图连线的操作超过限定时间仍未有响应。
ENETUNREACH 无法传送数据包至指定的主机。
EAFNOSUPPORT sockaddr结构的sa_family不正确。
EALREADY socket为不可阻断且先前的连线操作还未完成。

 

范例**

/* 利用socket的TCP client
此程序会连线TCP server,并将键盘输入的字符串传送给server。
TCP server范例请参考listen()。
*/
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define PORT 1234
#define SERVER_IP “127.0.0.1”
main()
{
int s;
struct sockaddr_in addr;
char buffer[256];
if((s = socket(AF_INET,SOCK_STREAM,0))<0){
perror(“socket”);
exit(1);
}
/* 填写sockaddr_in结构*/
bzero(&amp;addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr = inet_addr(SERVER_IP);
/* 尝试连线*/
if(connect(s,&amp;addr,sizeof(addr))<0){
perror(“connect”);
exit(1);
}
/* 接收由server端传来的信息*/
recv(s,buffer,sizeof(buffer),0);
printf(“%s\n”,buffer);
while(1){
bzero(buffer,sizeof(buffer));
/* 从标准输入设备取得字符串*/
read(STDIN_FILENO,buffer,sizeof(buffer));
/* 将字符串传给server端*/
if(send(s,buffer,sizeof(buffer),0)<0){
perror(“send”);
exit(1);
}
}
}
执行 $ ./connect
Welcome to server!
hi I am client! /*键盘输入*/
/*<Ctrl+C>中断程序*/

endprotoent(结束网络协议数据的读取)

相关函数 getprotoent,getprotobyname,getprotobynumber,setprotoent
表头文件 #include<netdb.h>
定义函数 void endprotoent(void);
函数说明 endprotoent()用来关闭由getprotoent()打开的文件。
返回值

 

范例**

参考getprotoent()

endservent(结束网络服务数据的读取)

相关函数 getservent,getservbyname,getservbyport,setservent
表头文件 #include<netdb.h>
定义函数 void endservent(void);
函数说明 endservent()用来关闭由getservent()所打开的文件。
返回值

 

范例**

参考getservent()。

getsockopt(取得socket状态)

相关函数 setsockopt
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int getsockopt(int s,int level,int optname,void*
optval,socklen_t* optlen);
函数说明 getsockopt()会将参数s所指定的socket状态返回。参数optname代表欲取得何种选项状态,而参数optval则指向欲保存结果的内存地址,参数optlen则为该空间的大小。参数level、optname请参考setsockopt()。
返回值 成功则返回0,若有错误则返回-1,错误原因存于errno
错误代码 EBADF 参数s 并非合法的socket处理代码
ENOTSOCK 参数s为一文件描述词,非socket
ENOPROTOOPT 参数optname指定的选项不正确
EFAULT 参数optval指针指向无法存取的内存空间

 

范例**

#include<sys/types.h>
#include<sys/socket.h>
main()
{
int s,optval,optlen = sizeof(int);
if((s = socket(AF_INET,SOCK_STREAM,0))<0) perror
(“socket”);
getsockopt(s,SOL_SOCKET,SO_TYPE,&amp;optval,&amp;optlen);
printf(“optval = %d\n”,optval);
close(s);}
执行 optval = 1 /*SOCK_STREAM的定义正是此值*/

htonl(将32位主机字符顺序转换成网络字符顺序)

相关函数 htons,ntohl,ntohs
表头文件 #include<netinet/in.h>
定义函数 unsigned long int htonl(unsigned long int hostlong);
函数说明 htonl()用来将参数指定的32位hostlong 转换成网络字符顺序。
返回值 返回对应的网络字符顺序。
 

范例**

参考getservbyport()或connect()。

htons(将16位主机字符顺序转换成网络字符顺序)

相关函数 htonl,ntohl,ntohs
表头文件 #include<netinet/in.h>
定义函数 unsigned short int htons(unsigned short int hostshort);
函数说明 htons()用来将参数指定的16位hostshort转换成网络字符顺序。
返回值 返回对应的网络字符顺序。

 

范例**

参考connect()。

inet_addr(将网络地址转成二进制的数字)

相关函数 inet_aton,inet_ntoa
表头文件 #include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
定义函数 unsigned long int inet_addr(const char *cp);
函数说明 inet_addr()用来将参数cp所指的网络地址字符串转换成网络所使用的二进制数字。网络地址字符串是以数字和点组成的字符串,例如:

        “163.13.132.68”。
返回值 成功则返回对应的网络二进制的数字,失败返回-1。

范例**

inet_aton(将网络地址转成网络二进制的数字)

相关函数 inet_addr,inet_ntoa
表头文件 #include<sys/scoket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
定义函数 int inet_aton(const char * cp,struct in_addr *inp);
函数说明 inet_aton()用来将参数cp所指的网络地址字符串转换成网络使用的二进制的数字,然后存于参数inp所指的in_addr结构中。
结构in_addr定义如下
struct in_addr
{
&nbsp;&nbsp;&nbsp;  unsigned long int s_addr;
};
返回值 成功则返回非0值,失败则返回0。
 

范例**

inet_ntoa(将网络二进制的数字转换成网络地址)

相关函数 inet_addr,inet_aton
表头文件 #include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
定义函数 char * inet_ntoa(struct in_addr in);
函数说明 inet_ntoa()用来将参数in所指的网络二进制的数字转换成网络地址,然后将指向此网络地址字符串的指针返回。
返回值 成功则返回字符串指针,失败则返回NULL。

范例**

listen(等待连接)

相关函数 socket,bind,accept,connect
表头文件 #include<sys/socket.h>
定义函数 int listen(int s,int backlog);
函数说明 listen()用来等待参数s 的socket连线。参数backlog指定同时能处
理的最大连接要求,如果连接数目达此上限则client端将收到
ECONNREFUSED的错误。Listen()并未开始接收连线,只是设置
socket为listen模式,真正接收client端连线的是accept()。通常
listen()会在socket(),bind()之后调用,接着才调用accept()。
返回值 成功则返回0,失败返回-1,错误原因存于errno
附加说明 listen()只适用SOCK_STREAM或SOCK_SEQPACKET的socket类型。如果socket为AF_INET则参数backlog  最大值可设至128。
错误代码 EBADF 参数sockfd非合法socket处理代码
EACCESS 权限不足
EOPNOTSUPP 指定的socket并未支援listen模式。

 

范例**

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#define PORT 1234
#define MAXSOCKFD 10
main()
{
int sockfd,newsockfd,is_connected[MAXSOCKFD],fd;
struct sockaddr_in addr;
int addr_len = sizeof(struct sockaddr_in);
fd_set readfds;
char buffer[256];
char msg[ ] =”Welcome to server!”;
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0){
perror(“socket”);
exit(1);
}
bzero(&amp;addr,sizeof(addr));
addr.sin_family =AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,&amp;addr,sizeof(addr))<0){
perror(“connect”);
exit(1);
}
if(listen(sockfd,3)<0){
perror(“listen”);
exit(1);
}
for(fd=0;fd<MAXSOCKFD;fd++)
is_connected[fd]=0;
while(1){
FD_ZERO(&amp;readfds);
FD_SET(sockfd,&amp;readfds);
for(fd=0;fd<MAXSOCKFD;fd++)
if(is_connected[fd]) FD_SET(fd,&amp;readfds);
if(!select(MAXSOCKFD,&amp;readfds,NULL,NULL,NULL))continue;
for(fd=0;fd<MAXSOCKFD;fd++)
if(FD_ISSET(fd,&amp;readfds)){
if(sockfd = =fd){
if((newsockfd = accept (sockfd,&amp;addr,&amp;addr_len))<0)
perror(“accept”);
write(newsockfd,msg,sizeof(msg));
is_connected[newsockfd] =1;
printf(“cnnect from %s\n”,inet_ntoa(addr.sin_addr));
}else{
bzero(buffer,sizeof(buffer));
if(read(fd,buffer,sizeof(buffer))<=0){
printf(“connect closed.\n”);
is_connected[fd]=0;
close(fd);
}else
printf(“%s”,buffer);
}
}
}
}
执行 $ ./listen
connect from 127.0.0.1
hi I am client
connected closed.

ntohl(将32位网络字符顺序转换成主机字符顺序)

相关函数 htonl,htons,ntohs
表头文件 #include<netinet/in.h>
定义函数 unsigned long int ntohl(unsigned long int netlong);
函数说明 ntohl()用来将参数指定的32位netlong转换成主机字符顺序。
返回值 返回对应的主机字符顺序。

 

范例**

参考getservent()。

ntohs(将16位网络字符顺序转换成主机字符顺序)

相关函数 htonl,htons,ntohl
表头文件 #include<netinet/in.h>
定义函数 unsigned short int ntohs(unsigned short int netshort);
函数说明 ntohs()用来将参数指定的16位netshort转换成主机字符顺序。
返回值 返回对应的主机顺序。
 

范例**

参考getservent()。

recv(经socket接收数据)

相关函数 recvfrom,recvmsg,send,sendto,socket
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int recv(int s,void *buf,int len,unsigned int flags);
函数说明 recv()用来接收远端主机经指定的socket传来的数据,并把数据存到由参数buf 指向的内存空间,参数len为可接收数据的最大长度。
参数 flags一般设0。其他数值定义如下:
MSG_OOB 接收以out-of-band 送出的数据。
MSG_PEEK 返回来的数据并不会在系统内删除,如果再调用recv()会
返回相同的数据内容。
MSG_WAITALL强迫接收到len大小的数据后才能返回,除非有错误或
信号产生。
MSG_NOSIGNAL此操作不愿被SIGPIPE信号中断返回值成功则返回接收
到的字符数,失败返回-1,错误原因存于errno中。
错误代码 EBADF 参数s非合法的socket处理代码
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断
EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断
ENOBUFS 系统的缓冲内存不足。
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。

 

范例**

参考listen()。

recvfrom(经socket接收数据)

相关函数 recv,recvmsg,send,sendto,socket
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int recvfrom(int s,void *buf,int len,unsigned int flags ,struct    sockaddr *from ,int *fromlen);
函数说明 recv()用来接收远程主机经指定的socket 传来的数据,并把数据存到由参数buf 指向的内存空间,参数len  为可接收数据的最大长度。参数flags 一般设0,其他数值定义请参考recv()。参数from用来指定欲传送的网络地址,结构sockaddr  请参考bind()。参数fromlen为sockaddr的结构长度。
返回值 成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。
错误代码 EBADF 参数s非合法的socket处理代码
EFAULT 参数中有一指针指向无法存取的内存空间。
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断。
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。
范例 /*利用socket的UDP client
此程序会连线UDP server,并将键盘输入的字符串传给server。

 

UDP server 范例请参考sendto()。范例:**

*/
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/typs.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#define PORT 2345
#define SERVER_IP “127.0.0.1”
main()
{
int s,len;
struct sockaddr_in addr;
int addr_len =sizeof(struct sockaddr_in);
char buffer[256];
/* 建立socket*/
if((s = socket(AF_INET,SOCK_DGRAM,0))<0){
perror(“socket”);
exit(1);
}
/* 填写sockaddr_in*/
bzero(&amp;addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(SERVER_IP);
while(1){
bzero(buffer,sizeof(buffer));
/* 从标准输入设备取得字符串*/
len =read(STDIN_FILENO,buffer,sizeof(buffer));
/* 将字符串传送给server端*/
sendto(s,buffer,len,0,&amp;addr,addr_len);
/* 接收server端返回的字符串*/
len = recvfrom(s,buffer,sizeof(buffer),0,&amp;addr,&amp;addr_len);
printf(“receive: %s”,buffer);
}
}
执行 (先执行udp server 再执行udp client)
hello /*从键盘输入字符串*/
receive: hello /*server端返回来的字符串*/

范例**

**参考recvfrom()。

send(经socket传送数据)

相关函数 sendto,sendmsg,recv,recvfrom,socket
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int send(int s,const void * msg,int len,unsigned int falgs);
函数说明 send()用来将数据由指定的socket 传给对方主机。参数s为已建立好连接的socket。参数msg指向欲连线的数据内容,参数len则为数据长度。参数flags一般设0,其他数值定义如下
MSG_OOB 传送的数据以out-of-band 送出。
MSG_DONTROUTE 取消路由表查询
MSG_DONTWAIT 设置为不可阻断运作
MSG_NOSIGNAL 此动作不愿被SIGPIPE 信号中断。
返回值 成功则返回实际传送出去的字符数,失败返回-1。错误原因存于errno
错误代码 EBADF 参数s 非合法的socket处理代码。
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此操作会令进程阻断,但参数s的socket为不可阻断。
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。
 

范例**

参考connect()

sendmsg(经socket传送数据)

相关函数 send,sendto,recv,recvfrom,recvmsg,socket
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int sendmsg(int s,const strcut msghdr *msg,unsigned int flags);
函数说明 sendmsg()用来将数据由指定的socket传给对方主机。参数s为已建立好连线的socket,如果利用UDP协议则不需经过连线操作。参数msg  指向欲连线的数据结构内容,参数flags一般默认为0,详细描述请参考send()。
结构msghdr定义如下
struct msghdr
{
void *msg_name; /*Address to send to /receive from . */
socklen_t msg_namelen; /* Length of addres data */
strcut iovec * msg_iov; /* Vector of data to send/receive
into */
size_t msg_iovlen; /* Number of elements in the vector */
void * msg_control; /* Ancillary dat */
size_t msg_controllen; /* Ancillary data buffer length */
int msg_flags; /* Flags on received message */
};
返回值 成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno
错误代码 EBADF 参数s 非合法的socket处理代码。
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此操作会令进程阻断,但参数s的socket为不可阻断。
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。** 

范例**

参考sendto()。

sendto(经socket传送数据)

相关函数 send , sendmsg,recv , recvfrom , socket
表头文件&nbsp; #include < sys/types.h >

         #include < sys/socket.h >
定义函数 int sendto ( int s , const void * msg, int len, unsigned int flags, const struct sockaddr * to , int tolen ) ;
函数说明 sendto() 用来将数据由指定的socket传给对方主机。参数s为已建好连线的socket,如果利用UDP协议则不需经过连线操作。参数msg指向欲连线的数据内容,参数flags 一般设0,详细描述请参考send()。参数to用来指定欲传送的网络地址,结构sockaddr请参考bind()。参数tolen为sockaddr的结果长度。
返回值 成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno 中。
错误代码 EBADF 参数s非法的socket处理代码。
EFAULT 参数中有一指针指向无法存取的内存空间。
WNOTSOCK canshu s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此动作会令进程阻断,但参数s的soket为补课阻断的。
ENOBUFS 系统的缓冲内存不足。
EINVAL 传给系统调用的参数不正确。
 

范例**

#include < sys/types.h >
#include < sys/socket.h >
# include <netinet.in.h>
#include <arpa.inet.h>
#define PORT 2345 /*使用的port*/
main(){
int sockfd,len;
struct sockaddr_in addr;
char buffer[256];
/*建立socket*/
if(sockfd=socket (AF_INET,SOCK_DGRAM,0))<0){
perror (“socket”);
exit(1);
}
/*填写sockaddr_in 结构*/
bzero ( &amp;addr, sizeof(addr) );
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr=hton1(INADDR_ANY) ;
if (bind(sockfd, &amp;addr, sizeof(addr))<0){
perror(“connect”);
exit(1);
}
while(1){
bezro(buffer,sizeof(buffer));
len = recvfrom(socket,buffer,sizeof(buffer), 0 , &amp;addr
&amp;addr_len);
/*显示client端的网络地址*/
printf(“receive from %s\n “ , inet_ntoa( addr.sin_addr));
/*将字串返回给client端*/
sendto(sockfd,buffer,len,0,&amp;addr,addr_len);”
}
}
执行 请参考recvfrom()

setprotoent(打开网络协议的数据文件)

相关函数 getprotobyname, getprotobynumber, endprotoent
表头文件 #include <netdb.h>
定义函数 void setprotoent (int stayopen);
函数说明 setprotoent()用来打开/etc/protocols, 如果参数stayopen值为1,则接下来的getprotobyname()或getprotobynumber()将不会自动关闭此文件。

范例**

setservent(打开主机网络服务的数据文件)

相关函数 getservent, getservbyname, getservbyport, endservent
表头文件 #include < netdb.h >
定义函数 void setservent (int stayopen);
函数说明 setservent()用来打开/etc/services,如果参数stayopen值为1,则接下来的getservbyname()或getservbyport()将补回自动关闭文件。
 

范例**

setsockopt(设置socket状态)

相关函数 getsockopt
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int setsockopt(int s,int level,int optname,const void *
optval,,socklen_toptlen);
函数说明 setsockopt()用来设置参数s所指定的socket状态。参数level代表
欲设置的网络层,一般设成SOL_SOCKET以存取socket层。参数
optname代表欲设置的选项,有下列几种数值:
SO_DEBUG 打开或关闭排错模式
SO_REUSEADDR 允许在bind()过程中本地地址可重复使用
SO_TYPE 返回socket形态。
SO_ERROR 返回socket已发生的错误原因
SO_DONTROUTE 送出的数据包不要利用路由设备来传输。
SO_BROADCAST 使用广播方式传送
SO_SNDBUF 设置送出的暂存区大小
SO_RCVBUF 设置接收的暂存区大小
SO_KEEPALIVE 定期确定连线是否已终止。
SO_OOBINLINE 当接收到OOB 数据时会马上送至标准输入设备
SO_LINGER 确保数据安全且可靠的传送出去。
参数 optval代表欲设置的值,参数optlen则为optval的长度。
返回值 成功则返回0,若有错误则返回-1,错误原因存于errno。
附加说明 EBADF 参数s并非合法的socket处理代码
ENOTSOCK 参数s为一文件描述词,非socket
ENOPROTOOPT 参数optname指定的选项不正确。
EFAULT 参数optval指针指向无法存取的内存空间。

 

范例**

参考getsockopt()。

shutdown(终止socket通信)

相关函数 socket,connect
表头文件 #include<sys/socket.h>
定义函数 int shutdown(int s,int how);
函数说明 shutdown()用来终止参数s所指定的socket连线。参数s是连线中的
socket处理代码,参数how有下列几种情况:
how=0 终止读取操作。
how=1 终止传送操作
how=2 终止读取及传送操作
返回值 成功则返回0,失败返回-1,错误原因存于errno。
错误代码 EBADF 参数s不是有效的socket处理代码
ENOTSOCK 参数s为一文件描述词,非socket
ENOTCONN 参数s指定的socket并未连线
 

范例**

socket(建立一个socket通信)

相关函数 accept,bind,connect,listen
表头文件 #include<sys/types.h>
#include<sys/socket.h>
定义函数 int socket(int domain,int type,int protocol);
函数说明 socket()用来建立一个新的socket,也就是向系统注册,通知系统建立一通信端口。参数domain   指定使用何种的地址类型,完整的定义在/usr/include/bits/socket.h 内,底下是常见的协议:
PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX 进程通信协议
PF_INET?AF_INET Ipv4网络协议
PF_INET6/AF_INET6 Ipv6 网络协议
PF_IPX/AF_IPX IPX-Novell协议
PF_NETLINK/AF_NETLINK 核心用户接口装置
PF_X25/AF_X25 ITU-T X.25/ISO-8208 协议
PF_AX25/AF_AX25 业余无线AX.25协议
PF_ATMPvc/AF_ATMPvc 存取原始ATM PVCs
PF_APPLETALK/AF_APPLETALK appletalk(DDP)协议
PF_PACKET/AF_PACKET 初级封包接口
参数 type有下列几种数值:
SOCK_STREAM 提供双向连续且可信赖的数据流,即TCP。支持
OOB 机制,在所有数据传送前必须使用connect()来建立连线状态。
SOCK_DGRAM 使用不连续不可信赖的数据包连接
SOCK_SEQPACKET 提供连续可信赖的数据包连接
SOCK_RAW 提供原始网络协议存取
SOCK_RDM 提供可信赖的数据包连接
SOCK_PACKET 提供和网络驱动程序直接通信。
protocol用来指定socket所使用的传输协议编号,通常此参考不用
管它,设为0即可。
返回值 成功则返回socket处理代码,失败返回-1。
错误代码 EPROTONOSUPPORT 参数domain指定的类型不支持参数type或protocol指定的协议
ENFILE 核心内存不足,无法建立新的socket结构
EMFILE 进程文件表溢出,无法再建立新的socket
EACCESS 权限不足,无法建立type或protocol指定的协议
ENOBUFS/ENOMEM 内存不足
EINVAL 参数domain/type/protocol不合法
 

范例**

参考connect()。

linuxC环境变量篇

getenv(取得环境变量内容)

相关函数 putenv,setenv,unsetenv
表头文件 #include<stdlib.h>
定义函数 char * getenv(const char *name);
函数说明 getenv()用来取得参数name环境变量的内容。参数name为环境变量
的名称,如果该变量存在则会返回指向该内容的指针。环境变量的
格式为name=value。
返回值 执行成功则返回指向该内容的指针,找不到符合的环境变量名称则
返回NULL。

 

范例**

#include<stdlib.h>
mian()
{
char *p;
if((p = getenv(“USER”)))
printf(“USER=%s\n”,p);
}
执行 USER = root

putenv(改变或增加环境变量)

相关函数 getenv,setenv,unsetenv
表头文件 #include4<stdlib.h>
定义函数 int putenv(const char * string);
函数说明 putenv()用来改变或增加环境变量的内容。参数string的格式为
name=value,如果该环境变量原先存在,则变量内容会依参数
string改变,否则此参数内容会成为新的环境变量。
返回值 执行成功则返回0,有错误发生则返回-1。
错误代码 ENOMEM 内存不足,无法配置新的环境变量空间。

 

范例**

#include<stdlib.h>
main()
{
char *p;
if((p = getenv(“USER”)))
printf(“USER =%s\n”,p);
putenv(“USER=test”);
printf(“USER+5s\n”,getenv(“USER”));
}
执行 USER=root
USER=root

setenv(改变或增加环境变量)

相关函数 getenv,putenv,unsetenv
表头文件 #include<stdlib.h>
定义函数 int setenv(const char *name,const char * value,int
overwrite);
函数说明 setenv()用来改变或增加环境变量的内容。参数name为环境变量名
称字符串。
参数 value则为变量内容,参数overwrite用来决定是否要改变已存在的
环境变量。如果overwrite不为0,而该环境变量原已有内容,则原
内容会被改为参数value所指的变量内容。如果overwrite为0,且该
环境变量已有内容,则参数value会被忽略。
返回值 执行成功则返回0,有错误发生时返回-1。
错误代码 ENOMEM 内存不足,无法配置新的环境变量空间

 

范例**

#include<stdlib.h>
main()
{
char * p;
if((p=getenv(“USER”)))
printf(“USER =%s\n”,p);
setenv(“USER”,”test”,1);
printf(“USER=%s\n”,getenv(“USEr”));
unsetenv(“USER”);
printf(“USER=%s\n”,getenv(“USER”));
}
执行 USER = root
USER = test
USER = (null)

linuxC常用数学函数

abs(计算整型数的绝对值)

相关函数 labs, fabs
表头文件 #include<stdlib.h>
定义函数 int abs (int j)
函数说明 abs()用来计算参数j的绝对值,然后将结果返回。
返回值 返回参数j的绝对值结果。

范例**

#ingclude <stdlib.h>
main(){
int ansert;
answer = abs(-12);
printf("|-12| = %d\n", answer);
}

执行 |-12| = 12

acos(取反余弦函数数值)

相关函数 asin , atan , atan2 , cos , sin , tan
表头文件 #include <math.h>
定义函数 double acos (double x);
函数说明 acos()用来计算参数x的反余弦值,然后将结果返回。参数x范围为-1至1之间,超过此范围则会失败。
返回值 返回0至PI之间的计算结果,单位为弧度,在函数库中角度均以弧度来表示。
错误代码 EDOM参数x超出范围。
附加说明 使用GCC编译时请加入-lm。

范例**

#include <math.h>
main (){
double angle;
angle = acos(0.5);
printf("angle = %f\n", angle);
}

执行 angle = 1.047198

asin(取反正弦函数值)

相关函数 acos , atan , atan2 , cos , sin , tan
表头文件 #include <math.h>
定义函数 double asin (double x)
函数说明 asin()用来计算参数x的反正弦值,然后将结果返回。参数x范围为-1至1之间,超过此范围则会失败。
返回值 返回-PI/2之PI/2之间的计算结果。
错误代码 EDOM参数x超出范围
附加说明 使用GCC编译时请加入-lm

范例**

#include<math.h>
main()
{
double angle;
angle = asin (0.5);
printf("angle = %f\n",angle);
}

执行 angle = 0.523599

atan(取反正切函数值)

相关函数 acos,asin,atan2,cos,sin,tan
表头文件 #include<math.h>
定义函数 double atan(double x);
函数说明 atan()用来计算参数x的反正切值,然后将结果返回。
返回值 返回-PI/2至PI/2之间的计算结果。
附加说明 使用GCC编译时请加入-lm

 

范例**

#include<math.h>
main()
{
double angle;
angle =atan(1);
printf("angle = %f\n",angle);
}
执行 angle = 1.570796

atan2(取得反正切函数值)

相关函数 acos,asin,atan,cos,sin,tan
表头文件 #include<math.h>
定义函数 double atan2(double y,double x);
函数说明 atan2()用来计算参数y/x的反正切值,然后将结果返回。
返回值 返回-PI/2 至PI/2 之间的计算结果。
附加说明 使用GCC编译时请加入-lm。
 

范例**

#include<math.h>
main()
{
double angle;
angle = atan2(1,2);
printf("angle = %f\n", angle);
}

执行 angle = 0.463648

ceil(取不小于参数的最小整型数)

相关函数 fabs
表头文件 #include <math.h>
定义函数 double ceil (double x);
函数说明 ceil()会返回不小于参数x的最小整数值,结果以double形态返回。
返回值 返回不小于参数x的最小整数值。
附加说明 使用GCC编译时请加入-lm。

范例**

#include<math.h>
main()
{
double value[ ]={4.8,1.12,-2.2,0};
int i;
for (i=0;value[i]!=0;i++)
printf("%f=>%f\n",value[i],ceil(value[i]));
}
执行 4.800000=>5.000000
1.120000=>2.000000
-2.200000=>-2.000000
 

cos(取余玄函数值)

相关函数 acos,asin,atan,atan2,sin,tan
表头文件 #include<math.h>
定义函数 double cos(double x);
函数说明 cos()用来计算参数x 的余玄值,然后将结果返回。
返回值 返回-1至1之间的计算结果。
附加说明 使用GCC编译时请加入-lm。

范例**

#include<math.h>
main()
{
double answer = cos(0.5);
printf("cos (0.5) = %f\n",answer);
}
执行 cos(0.5) = 0.877583
 

cosh(取双曲线余玄函数值)

相关函数 sinh,tanh
表头文件 #include<math.h>
定义函数 double cosh(double x);
函数说明 cosh()用来计算参数x的双曲线余玄值,然后将结果返回。数学定义
式为:(exp(x)+exp(-x))/2。
返回值 返回参数x的双曲线余玄值。
附加说明 使用GCC编译时请加入-lm。

范例**

#include<math.h>
main()
{
double answer = cosh(0.5);
printf("cosh(0.5) = %f\n",answer);
}
执行 cosh(0.5) = 1.127626
 

exp(计算指数)

相关函数 log,log10,pow
表头文件 #include<math.h>
定义函数 double exp(double x);
函数说明 exp()用来计算以e为底的x次方值,即ex值,然后将结果返回。
返回值 返回e的x次方计算结果。
附加说明 使用GCC编译时请加入-lm。

 

范例**

#include<math.h>
main()
{
double answer;
answer = exp (10);
printf("e^10 =%f\n", answer);
}
执行 e^10 = 22026.465795

frexp(将浮点型数分为底数与指数)

相关函数 ldexp,modf
表头文件 #include<math.h>
定义函数 double frexp( double x, int *exp);
函数说明 frexp()用来将参数x 的浮点型数切割成底数和指数。底数部分直接
返回,指数部分则借参数exp 指针返回,将返回值乘以2 的exp次方
即为x的值。
返回值 返回参数x的底数部分,指数部分则存于exp指针所指的地址。
附加说明 使用GCC编译时请加入-lm。

范例**

#include <math.h>
main()
{
int exp;
double fraction;
fraction = frexp (1024,&amp;exp);
printf("exp = %d\n",exp);
printf("fraction = %f\n", fraction);
}
执行 exp = 11
fraction = 0.500000 /* 0.5*(2^11)=1024*/

ldexp(计算2的次方值)

相关函数 frexp
表头文件 #include<math.h>
定义函数 double ldexp(double x,int exp);
函数说明 ldexp()用来将参数x乘上2的exp次方值,即x*2exp。
返回值 返回计算结果。
附加说明 使用GCC编译时请加入-lm。

范例**

&nbsp;/* 计算3*(2^2)=12 */
#include<math.h>
main()
{
int exp;
double x,answer;
answer = ldexp(3,2);
printf("3*2^(2) = %f\n",answer);
}
执行 3*2^(2) = 12.000000

log(计算以e 为底的对数值)

相关函数 exp,log10,pow
表头文件 #include <math.h>
定义函数 double log (double x);
函数说明 log()用来计算以e为底的x 对数值,然后将结果返回。
返回值 返回参数x的自然对数值。
错误代码 EDOM 参数x为负数,ERANGE 参数x为零值,零的对数值无定义。
附加说明 使用GCC编译时请加入-lm。

范例**

#include<math.h>
main()
{
double answer;
answer = log (100);
printf("log(100) = %f\n",answer);
}
执行 log(100) = 4.605170

log10(计算以10 为底的对数值)

相关函数 exp,log,pow
表头文件 #include<math.h>
定义函数 double log10(double x);
函数说明 log10()用来计算以10为底的x对数值,然后将结果返回。
返回值 返回参数x以10为底的对数值。
错误代码 EDOM参数x为负数。RANGE参数x为零值,零的对数值无定义。
附加说明 使用GCC编译时请加入-lm。

范例**

#include<math.h>
main()
{
double answer;
answer = log10(100);
printf("log10(100) = %f\n",answer);
}
执行 log10(100) = 2.000000

pow(计算次方值)

相关函数 exp,log,log10
表头文件 #include<math.h>
定义函数 double pow(double x,double y);
函数说明 pow()用来计算以x为底的y次方值,即xy值,然后将结果返回。
返回值 返回x的y次方计算结果。
错误代码 EDOM 参数x为负数且参数y不是整数。
附加说明 使用GCC编译时请加入-lm。

范例**

#include <math.h>
main()
{
double answer;
answer =pow(2,10);
printf("2^10 = %f\n", answer);
}
执行 2^10 = 1024.000000

sin(取正玄函数值)

相关函数 acos,asin,atan,atan2,cos,tan
表头文件 #include<math.h>
定义函数 double sin(double x);
函数说明 sin()用来计算参数x的正玄值,然后将结果返回。
返回值 返回-1 至1之间的计算结果。
附加说明 使用GCC编译时请加入-lm。

范例**

#include<math.h>
main()
{
double answer = sin (0.5);
printf("sin(0.5) = %f\n",answer);
}
执行 sin(0.5) = 0.479426

sinh(取双曲线正玄函数值)

相关函数 cosh,tanh
表头文件 #include<math.h>
定义函数 double sinh( double x);
函数说明 sinh()用来计算参数x的双曲线正玄值,然后将结果返回。数学定义
式为:(exp(x)-exp(-x))/2。
返回值 返回参数x的双曲线正玄值。
附加说明 使用GCC编译时请加入-lm。

 

范例**

#include<math.h>
main()
{
double answer = sinh (0.5);
printf("sinh(0.5) = %f\n",answer);
}
执行 sinh(0.5) = 0.521095

sqrt(计算平方根值)

相关函数 hypotq
表头文件 #include<math.h>
定义函数 double sqrt(double x);
函数说明 sqrt()用来计算参数x的平方根,然后将结果返回。参数x必须为正
数。
返回值 返回参数x的平方根值。
错误代码 EDOM 参数x为负数。
附加说明 使用GCC编译时请加入-lm。

 

范例**

/* 计算200的平方根值*/
#include<math.h>
main()
{
double root;
root = sqrt (200);
printf("answer is %f\n",root);
}
执行 answer is 14.142136

tan(取正切函数值)

相关函数 atan,atan2,cos,sin
表头文件 #include <math.h>
定义函数 double tan(double x);
函数说明 tan()用来计算参数x的正切值,然后将结果返回。
返回值 返回参数x的正切值。
附加说明 使用GCC编译时请加入-lm。

 

范例**

#include<math.h>
main()
{
double answer = tan(0.5);
printf("tan (0.5) = %f\n",answer);
}
执行 tan(0.5) = 0.546302

tanh(取双曲线正切函数值)

相关函数 cosh,sinh
表头文件 #include<math.h>
定义函数 double tanh(double x);
函数说明 tanh()用来计算参数x的双曲线正切值,然后将结果返回。数学定义
式为:sinh(x)/cosh(x)。
返回值 返回参数x的双曲线正切值。
附加说明 使用GCC编译时请加入-lm。

 

范例**

#include<math.h>
main()
{
double answer = tanh(0.5);
printf("tanh(0.5) = %f\n",answer);
}
执行 tanh(0.5) = 0.462117

C语言入门

#Hello World

#include <stdio.h>

int main() //pre-defined function
{
    printf("Hello World 123");
    return 0;
}

#Main is Main

#include <stdio.h>

int printSomething()
{
    printf("I will not be executed");
    return 0;
}

int main()
{
    printf("I'm a great guy");
    return 0;
}

#Print Something

#include <stdio.h>

void printSomething()
{
    printf("I will not be executed");
}

int main()
{
    printf("I'm a great guy");
    printSomething();
    return 0;
}

#First Variable

#include <stdio.h>

//Variable - value can change
//Assignment Operator

/////////
//  3  //
////////
//score - integer
int main()
{
    int score;//1854054454 
    //TYPE NAME;
    //d - integer
    printf("score : %d",score);
    return 0;
}

#Two Variables

#include <stdio.h>

//Assignment Operator

//////////////////
//  20  //
//////////////////
//score - integer
int main()
{
    int score1;//
    int score2;

    score1 = 5;
    score2 = 15;

    printf("score1 : %d \n",score1);

    printf("score2 : %d",score2);
    return 0;
}

#Sum of Two Variables

#include <stdio.h>

//Assignment Operator

//////////////////
//  20  //
//////////////////
//score - integer
int main()
{
    int score1;//
    int score2;
    int sum;

    score1 = 5;
    score2 = 15;

    sum = score1 + score2;

    printf("score1:%d score2:%d sum:%d",
            score1,score2,sum);
    return 0;
}

#Swap Program

#include <stdio.h>

//Assignment Operator

///////////   ///////////
//   10    //    //  10     //
//////////    //////////
// i               j

//score - integer
int main()
{
    int i=5;
    int j=10;
    int k;

    k = i;//k=5,i=5,j=10
    i=j;//k=5,i=10,j=10
    j=k;//k=5,i=10,j=5

    printf("i:%d j:%d",
            i,j);

    return 0;
}

#Floating point variable

#include <stdio.h>

int main()
{
    int i=1;
    int j=10;

    float avg;//1.5,2.5

    avg = (i+j)/2.0;

    printf("avg:%f",avg);
    //d - integer
    //f - float

}

#Character Example

#include <stdio.h>

int main()
{
    int i=1;
    int j=10;

    char ch = 67;//ASCII

    printf("ch:%c",ch);//A
    //d - integer
    //f - float
    //c - character

}

#Function

#include <stdio.h>

//REturnType NameofFuntion()
//{
// BODY;
//}
void welcome() //declaration
{
    printf("Hi From in28Minutes.com\n");
}

int main()
{
    welcome(); //calling or invocation
    welcome();
    welcome();
}

#IF ELSE

#include <stdio.h>

void welcome()
{
    printf("Welcome to in28minutes.com\n");
}

void subscribe() //declaration
{
    printf("Subscribe at in28Minutes.com\n");
}

int main()
{
    int like=0;
    welcome(); //calling or invocation

    if(like) // true if like has non zero
    {
        subscribe();
    }
    else
    {
        printf("Please tell us what we can do to improve");
    }
}

#Nested If Else

#include <stdio.h>

int main()
{
    int score=3;
    //1 - Single 2- Double
    //3 - Triple 4 - Boundary 6 - Sixer

    if(score==1)
    {
        printf("Single");
    }
    else if(score==2)
    {
        printf("Double");
    }
    else
    {
        printf("Something Else");
    }
}

#Switch Statement

#include <stdio.h>

int main()
{
    int score=6;
    //1 - Single 2- Double
    //3 - Triple 4 - Boundary 6 - Sixer

    switch(score)
    {
    case 1 :
        printf("Single");
        break;
    case 2 :
        printf("Double");
        break;
    default:
        printf("Something Else");
        break;
    case 4:
        printf("Boundary");
        break;
    }
}

#Need for an Array

#include <stdio.h>

int main()
{
    int score1=6;
    int score2=15;
    int score3=145;
    int count = 0;

    if(score1>99)
        count = count + 1;

    if(score2>99)
        count = count + 1;

    if(score3>99)
        count = count + 1;

    printf("Number of Centuries %d",count);
}

#Array Basics

#include <stdio.h>
int main()
{
    int score1=106;
    int score2=15;
    int score3=145;
    int score4=23;

    int scores[10] = {106, 15, 145, 23};
                  // 0    1   2   3
    int scoresLength = 4;

    //How to read values?
    //printf("%d",scores[0]);
    //How to set values?
    scores[0] = 108;
    //How to find length of an array?
    //What is the default value?
    //printf("%d",scores[5]);//0
    //What if I try to bite more than I can Chew?
    printf("%d",scores[11]);//-1308602447

}

#For Loop Example

#include <stdio.h>
int main()
{

    int scores[] = {106, 15, 145, 23};
                  // 0    1   2   3
    int scoresLength = 4;

    for
    (
            int i = 0;//initialization
            i < scoresLength;//condition
            i++//increment
    )
    {
        printf(" %d ",scores[i]);
    }

}

#While Loop Example

#include <stdio.h>
int main()
{

    int scores[] = {106, 15, 145, 23, 235,235,235};
                  // 0    1   2   3
    int scoresLength = 7;

    int i = 0;//initialization

    while(i < scoresLength)//condition
    {//i:7
        printf(" %d ",scores[i]);
        i++;//increment
    }
    
    for(int i=0;i<scoresLength;i++)
    {
        printf(" %d ",scores[i]);
    }
}

#Do while Example

#include <stdio.h>
int main()
{

    int scores[] = {106, 15, 145, 23, 235,235,235};
                  // 0    1   2   3
    int scoresLength = 7;

    int i = 0;//initialization

    do
    {//i:7
        printf(" %d ",scores[i]);
        i++;//increment
    }
    while(i < scoresLength);//condition
}

#C Program : Print an Array

#include <stdio.h>

//returntype name(arguments)
void printArray(int array[],int length)
{
    for(int i=0;i<length;i++)
    {
        printf("%d ",array[i]);
    }
    printf("\n");
}

int main()
{
    int scoresTeam1[] = {10,101,25,47};
    int scoresLength = 4;
    int scoresTeam2[] = {10,100,5,7};

    printArray(scoresTeam1,scoresLength);
    printArray(scoresTeam2,scoresLength);
    return 0;
}

#Program - is number even?

#include <stdio.h>

//0 - false, anything non-zero - true (1,-1)
int isEven(int number)
{
    if(number%2==0)// 5%2==1 - comparision
        return 1;

    return 0;
}

//isEven
//2 - true
//3 - false
int main()
{
    printf("1:%d\n",isEven(1));
    printf("2:%d\n",isEven(2));
    return 0;
}



#Leap Year C Program

#include <stdio.h>

//0-false 1-true
int isLeapYear(int year)
{
    if(year%400==0)
        return 1;

    if(year%100==0)
        return 0;

    if(year%4==0)
        return 1;

    return 0;
}

//%4 = Leap YEar
//1900,2000,2100,2200,2300,2400

int main()
{
    printf("2000:%d\n",isLeapYear(2000));
    printf("1900:%d\n",isLeapYear(1900));
    printf("1904:%d\n",isLeapYear(1904));
    printf("1901:%d\n",isLeapYear(1901));

    return 0;
}

#Sum of first n numbers program

#include <stdio.h>

//0-false 1-true
int calculateSumUpto(int n)
{
    int result = 0;

    for(int i=1; i<=n; i++)
    {
        result = result + i;
    }

    return result;
    // 1 to n
    // result = result + index
}

// 5 =  1 to 5, 1 + 2 + ... + 5 = 15

int main()
{
    printf("upto 5:%d\n",calculateSumUpto(5));
    printf("upto 10:%d\n",calculateSumUpto(10));

    return 0;
}

#C Program Sum of First n even numbers

#include <stdio.h>

//0-false 1-true
int calculateSumEvenNumbersUpto(int n)
{
    int result = 0;

    for(int i=2; i<=n*2; i = i + 2) //1 to n 2,4,6,8,10
    {
        result = result + i; //1 to n  2 * 1 to 2 * n
    }

    return result;
    // 1 to n
    // result = result + index
}

// 5 =  1 to 5, 1 + 2 + ... + 5 = 15

int main()
{
    printf("upto 5:%d\n",calculateSumEvenNumbersUpto(5));
    printf("upto 10:%d\n",calculateSumEvenNumbersUpto(10));

    return 0;
}

#Divisors of a number

#include <stdio.h>

void printDivisors(int n)
{
    for(int i=2;i<n;i++){
        if(n%i ==0){
            printf("%d\n",i);
        }
    }
}

//12 - 2,3,4,6
int main()
{
    printDivisors(12);
    return 0;
}

#Prime Number Program

#include <stdio.h>

//0-Not prime
//1 - prime
// 12 (2, 3,4,...,11)
int isPrime(int n)
{
    for(int i=2;i<n;i++){
        if(n%i == 0){
            return 0;
        }
    }

    return 1;
}

//12 - 2,3,4,6
int main()
{
    printf("4 : %d\n",isPrime(4));
    printf("5 : %d\n",isPrime(5));
    return 0;
}

#Number of digits in a number

#include <stdio.h>

int numberOfDigits(int n) //345
{
    int temp = n;//0
    int count = 0;//3
    while(temp!=0)
    {
        count++;
        temp = temp/10;
    }
    return count;

}

//456 - 3
//24567 - 5

int main()
{
    printf("456: %d\n",numberOfDigits(456));
    printf("24567: %d\n",numberOfDigits(24567));
    return 0;
}

#Sum of Digits Program

#include <stdio.h>

//345
//34 - 5
//3  - 5 + 4
//0  - 5 + 4 + 3

int sumOfDigits(int n) //345
{
    int temp = n;//3
    int sum = 0;//0 + 5 + 4 + 3
    while(temp!=0)
    {
        sum = sum + temp % 10;
        temp = temp/10;
    }
    return sum;

}

//456 - 15
//24567 - 24

int main()
{
    printf("456: %d\n",sumOfDigits(456));
    printf("24567: %d\n",sumOfDigits(24567));
    return 0;
}

#Write to a file

#include <stdio.h>

struct Student
{
    char name[100];
    int marks;
    int year;
};

void writeStudentToFile(struct Student student)
{
    //Get a pointer to the opened file
    // w   1 = 1
    // r
    // a - 5 + 1 = 6
    FILE *fp = fopen("Student.dat","w");

    //Write to the file
    fprintf(fp,"%s %d %d\n",student.name,student.marks,student.year);

    //Close the file
    fclose(fp);
}

int main()
{
    struct Student student =
        {"in28Minutes",100,4};

    writeStudentToFile(student);
}

#Read From File

#include <stdio.h>

struct Student
{
    char name[100];
    int marks;
    int year;
};

struct Student readStudentFromFile()
{
    //Get a pointer to the opened file
    FILE *fp = fopen("Student.dat","r");
    struct Student student;

    //Read from the file
    fscanf(fp,"%s %d %d\n",student.name,&student.marks,&student.year);

    //Close the file
    fclose(fp);

    return student;
}

void printStudent(struct Student student)
{
    printf("%s %d %d\n",student.name,student.marks,student.year);
}

int main()
{
    struct Student student = readStudentFromFile();
    printStudent(student);
}