系统编程内容
文件I/O (输入/输出):
1)使用标准库函数如fopen, fclose, fread, fwrite, fgetc, fputc, fgets, fprintf, fscanf等进行文件操作。
2)使用open, close, read, write等系统调用来实现底层文件操作。
进程管理:
1)使用fork, exec系列函数来创建和执行新的进程。
2)使用wait, waitpid等函数来等待进程结束。
线程管理:
1)使用POSIX线程库(pthreads)中的函数如pthread_create, pthread_join, pthread_mutex_*等来管理线程。
内存管理:
1)使用malloc, calloc, realloc, free等函数进行动态内存分配。
2)使用mmap, munmap等系统调用进行内存映射。
信号处理:
1)使用signal, sigaction等函数来处理异步事件,如键盘中断(SIGINT)。
网络编程:
1)用套接字(sockets)API,包括socket, bind, listen, accept, connect, send, recv等函数进行网络通信。
系统调用:
1)直接使用系统调用,如stat, chmod, chown等,来执行文件属性修改等操作。
时间管理:
1)使用time, difftime, localtime, gmtime, strftime等函数来处理时间和日期。
系统信息获取:
1)使用uname, sysinfo等函数来获取系统相关信息。
错误处理:
1)理解并处理系统调用和库函数返回的错误,通常通过检查返回值和使用errno全局变量。
安全性:
1)了解并实现基本的安全编程实践,如使用setuid, setgid等函数时的注意事项。
设备I/O:
1)直接与硬件设备进行交互,使用设备文件进行读写操作。
脚本编程:
1)虽然不是C语言的一部分,但编写shell脚本与C程序结合使用也是Linux系统编程的一部分。
编译和链接:
1)使用编译器(如gcc)和链接器(如ld)来编译和链接程序。
调试和性能分析:
1)使用调试工具(如gdb)和性能分析工具(如valgrind)来调试和优化程序。
标准IO
标准I/O(Standard Input/Output)是C语言中用于输入和输出操作的一套函数库,由ANSI C标准定义。它是由Dennis Ritchie和其他C语言的先驱者设计的,目的是提供一个统一的接口来处理数据流。以下是一些关于标准I/O的关键点:
-
流(Stream)的概念:
标准I/O使用流的概念来处理输入和输出。流可以是文件、键盘、屏幕等。
-
缓冲机制:
标准I/O库通常使用缓冲区来提高I/O操作的效率。 这意味着数据首先被写入内存中的缓冲区, 然后在缓冲区满了或者调用了特定的函数(如fflush)时才被发送到目标设备。
-
格式化输入输出:
标准I/O提供了格式化输入输出的功能,允许程序员指定数据的格式,如宽度、精度等。
-
主要函数:
fopen: 打开一个文件,并返回一个指向FILE对象的指针。 fclose: 关闭一个已经打开的文件流。 fread: 从文件中读取数据到缓冲区。 fwrite: 将数据从缓冲区写入文件。 fgetc/getc: 从流中读取一个字符。 fputc/putc: 向流中写入一个字符。 fgets: 从流中读取一行数据。 fputs: 向流中写入一个字符串。 printf: 格式化输出到标准输出(通常是屏幕)。 scanf: 从标准输入(通常是键盘)读取格式化数据。 fprintf: 格式化输出到指定的文件流。 fscanf: 从指定的文件流读取格式化数据。
-
错误处理:
标准I/O提供了错误检测机制,如ferror函数可以检查流是否有错误发生。
-
标准流:
有三个预定义的流: stdin: 标准输入(通常是键盘)。 stdout: 标准输出(通常是屏幕)。 stderr: 标准错误输出,用于输出错误信息(也通常是屏幕)。
-
文件打开模式:
标准I/O支持多种文件打开模式,例如: "r":只读模式打开文件。 "w":只写模式打开文件,如果文件存在则覆盖。 "a":追加模式打开文件,如果文件存在则在文件末尾追加内容。 "r+":读写模式打开文件。
-
定位和重定向:
标准I/O允许使用fseek, ftell, rewind等函数对文件流进行定位。
-
临时文件:
可以使用tmpfile函数创建临时文件。
-
内存流:
可以使用fmemopen等函数在内存中创建流。
-
宽字符支持:
标准I/O还提供了对宽字符的支持,如wprintf和wscanf等函数。
标准I/O库是C语言中非常重要的一部分,它为程序员提供了一种简便的方式来处理各种输入和输出任务。
IO的分类
标准IO(Standard IO):ANSI C设计的一组用文件IO封装的操作库函数,通过头文件stdio.h进行操作。
文件IO(File IO):底层软件的系统调用,用于对文件进行读写操作。
ASCII码数据流:以ASCII码作为数据流的文本流。
二进制数据流:以二进制数据作为数据流的二进制流。
操作文件基本思路
文件操作三步骤:
1.打开 -- fopen //FILE open
2.读写 -- getchar/putchar
gets / puts
fread / fwrite
3.关闭 -- fclose
一、文件编程
1.fopen
FILE *fopen(const char *pathname, const char *mode);
参数:
1).const char *pathname:文件名/路径,这是char型指针,须在”文件名/路径“上加上双引号;
2).const char *mode:文件的操作权限,这里也是字符型指针,须在“操作权限”上加双引号;
2.fclose
fclose()函数用来关闭当前文件流,其原型为:
int fclose(FILE * stream);
参数】stream为文件流指针。【返回值】若关文件动作成功则返回0,有错误发生时则返回EOF,并把错误代码存到errno。fclose()用来关闭fopen()打开的文件,此动作会让缓冲区内的数据写入文件中,并释放系统所提供的文件资源。注意:使用fopen()打开的文件,一定要记得使用fclose()关闭,否则会出现很多意想不到的情况,例如对文件的更改没有被记录到磁盘上,其他进程无法存取该文件等。
举例:打开和关闭文件
#include <stdio.h>
int main(void)
{ FILE *pf; pf = fopen("file.in", "w+"); /*打开文件*/if(pf != NULL){printf("open file ok\n");}else{printf("open file error\n");}fclose(pf); return 0;
}
流指针:
3.FILE * fp
FILE * fp;//流指针------关联一个文件 FILE * 实际上是指向了一块内存空间(缓存,fileno)
#include<stdio.h>
typedef struct{// 缓冲区“满”或“空”的程度short level;// 文件状态标志unsigned flags;// 文件描述符char fd;// 如无缓冲区则不读取字符unsigned char hold;// 缓冲区的大小short bsize;// 数据缓冲区的读写位置unsigned char *baffer;// 指针指向当前文件的读写位置unsigned char *curp;// 临时文件,指示器unsigned istemp;// 用于有效性检查short token;
}FILE;
FILE*fp;
FILE其实是一个
结构体,用于表示一个打开的文件流。p
是一个指针,指向这个结构体的实例。FILE *
类型使得你可以通过 p
访问和操作与文件相关的各种数据和函数
4.fputc
int fputc(int c, FILE *stream);
功能:
向流中写入一个字符
参数:
c:要写入的字符
stream:文件流指针
返回值:
成功返回写入的字符ASCII码值
失败返回EOF
5.fgetc
int fgetc(FILE *stream);
功能:
从流中读取一个字符
参数:
stream:文件流指针
返回值:
成功返回读到字符的ASCII码值
读到文件末尾返回EOF(返回值与fputc一致)
失败返回EOF
c= fgetc(stdin);
fputc(c,stdout);
获取键盘上面的输入,显示到屏幕。
6.fgets:
char *fgets(char *s, int size, FILE *stream);
功能:
从stream流对象关联的文件中获取size大小字节的文本数据
并存储到s对应的本地内存(栈区数组,堆区内存)
参数: s 要存储数据的本地内存
size 要获取的数据长度,单位字节。
stream 要获取的目标文件流对象,
可以是stdin ,程序会阻塞等待
如果是普通文件fp 则指向文件第一行数据
返回值:成功 返回指向有效数据的首地址,一般等于s的地址
失败 或者 文件末尾 NULL;
fgets读取结束的条件:
1.EOF 文件结束
2.\n 读到 "换行符" 则读取结束 注意:会被保存到 buffer(保存数据的这块内存中)
3.size-1 个字符 最后一个字符为'\0' //按字符串读写,
7.fputs:
int fputs(const char *s, FILE *stream);
功能:
从s所在的本地内存中获取一行数据,
并写入stream对应的文件流对象。
参数: s 要写的信息,一般是固定的字符串或者有数据的数组。
stream 要写入的目标文件流对象
返回值:成功 nonnegative number on success(成功写入的字符个数(非负数))
失败 -1;
8.fread:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从指定的stream流对象中获取nmemeb个大小为size字节的数据块到ptr
所在的本地内存中。
参数:ptr 要存储数据的本地内存一般是数组或者结构体指针
size 单个数据块的元数据大小。最小单元的大小(为保证数据不会被截断,一般为1)
nmemb 要获取的数据块的个数,拷贝的数据块个数。(一般为sizeof(ptr))
stream 要获取数据的源文件流对象,如果是stdin表示从
键盘获取数据,如果是fp文件则表示从普通文件获取。
返回值:
成功 小于等于nemeb的整数,表示获取的数据长度
失败 小于0,结尾 0;
9.fwrite:
size_t fwrite(const void *ptr, size_t size,size_t nmemb, FILE *stream);
功能:从ptr所在本地内存中取出nmemb个大小为size的数据块写入到stream流对应
的文件流对象中。
参数:ptr 要写的数据块地址,一般是数组或者结构体指针
size 要写的数据块元数据大小,单位是字节(为保证数据不会被截断,一般为1)
nmemb 要写的数据块的个数(一般为sizeof(ptr))->1个1个读,到sizeof(ptr)为止
stream 要写的目标文件流对象。如果是stdout则表示数据会
写到终端屏幕显示,如果是fp的普通文件则会写入到文件中。
返回值:成功 小于等于nmemb 的个数。
失败 <0