剑客
关注科技互联网

Happy Study Linux 2 – C标准库

#include <string.h>

void *memset(void *s,int c ,size_t n);
返回值:s指向那,返回值的指针就指向那

将s所指的内存地址开始的n个字节都填充为c值,通常c值为0,把一块内存区清零

取字符串的长度

size_t strlen(const char *s);
返回值:字符串的长度

从s所指的第一个字符开始查找’/0’字符,查找就返回不包括’/0’在内的长度

拷贝字符串

strcpystrncpy 函数拷贝’/0’结尾的字符串,strncpy可以指定拷贝多少字节

void *memcpy(void *dest,const void *src,size_t n);
void *memmove(void *dest,const void *src,size_t n);
返回值:dest指针指向的位置

memcpy函数从src所指向的内存地址拷贝n个字节到dest所指向的内存地址,不会遇到 /0 就结束,而是一定会拷贝完n个字节

memmove也是从src所指的内存地址拷贝n个字节到dest所指的内存地址,和memcpy不同的在于memmove可以拷贝所指的内存区间可以出现重叠

链接字符串

char *strcat(chat *dest,const char *src);
char *strncat(char *dest,const char *src,size_t n);
返回值:dest指针所指向的地址

必须保证dest缓冲区足够大,strncat通过n指定一个长度,避免缓冲区溢出错误

比较字符串

int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
返回值:负值表示s1小于s2,0表示s1等于s2,正值表示s1大于s2

搜索字符串

char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
返回值:如果找到字符串c,返回字符串s中指向字符串c的指针,找不到返回NULL

分割字符串

char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);
返回值:返回指向下一个Token的指针,如果没有下一个Token了就返回NULL

参数str是待分割的字符串,delim是分隔符,可以指定一个或多个分隔符,strtok遇到其中任何一个分隔符就会分割字符串。

标准I/O库函数

fopen/fclose

打开文件是在操作系统中分配一些资源用于保存该文件的状态信息,并得到该文件的标识,根据标识对文件做操作,关闭文件是释放文件在操作系统中占用的资源,使文件的标识失效,就无法操作该文件

FILE *fopen(const char *path, const char *mode);
返回值:成功返回文件指针,失败返回NULL并设置errno

FILE是C标准库中定义的结构体类型

path是文件的路径,可以是相对和绝对

mode 标识打开方式 r只读 w只写 a末尾追加不存在创建 r+读写文件必须存在 w+读写不存在就创建 a+读和追加数据不存在则创建

int fclose(FILE *fp);
返回值:成功返回0,出错返回EOF并设置errno

将文件指针传给fclose可以关闭标识文件

stdin/stdout/stderr

为什么printf和scanf不用打开就可以对终端设备做操作?

在程序启动时(main函数还没开始执行前)会自动将终端打开三次,分别赋值给三个FILE*指针 stdin,stdout和stderr,这三个文件指针是libc中定义的全局变量,再stdio.h中声明,printf向stdout写,而canf从stdin读,通常stdin只用与读操作,称为标准输入,stdout只用于写操作,称为标准输出,stderr也只用于写操作,称为标准错误输出

errno与perror

errno在头文件errno.h声明,很多系统函数再错误返回时将错误原因记录再libc定义的全局变量errno中,每种错误原因对应一个错误码.

#include <stdio.h>
void perror(const char *s);

如果我们在程序中直接打印错误信息是一个整数值,看不出是什么错误,可以用perror函数讲错误信息打印到标准错误输出首先打印参数s所指的字符串然后打印:号,然后根据erron值打印错误原因

以字节为单位的I/O函数

fgetc函数从制定的文件中读一个字节,getchar从标准输入读一个字节,调用getchar()相当于调用fgetc(stdin);

操作读写位置的函数

#include <stdio.h>
int fseek(FUKE *stream,long offset,int whence);
返回值:成功返回0,出错返回-1并设置errno

long ftell(FILE *stream);
返回值:成功返回当前读写位置,出错返回-1并设置errno

void rewind(FILE *stream);

fseel的whence和offset参数共同决定了读写位置移动到何处

以字符串为单位的I/O函数

char *fgets(char *s,int size,FILE *stream);
返回值:成功时指针指向s地址,出错或者到文件尾部返回NULL

参数s是缓冲区的首地值,size是缓冲区的长度,

以记录为单位的I/O函数

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:读或写的记录数,成功时返回的记录数等于nmemb,出错或读到文件末尾时返回的记录数小于nmemb,也可能返回0

fewad和fwrite用于读写记录,记录指一串固定长度的字节,比如int,数组,参数size指出一条记录的长度,nmemb指出要读写多少条记录,这些记录在ptr所指的内存空间中连续存放,fread从文件stream中读出size nmemb个字节保存到ptr中,而fwrite把ptr中的size nmemb个字节写到文件stream中。

格式化I/O函数

#include <stdio.h>

int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);

#include <stdarg.h>

int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);

返回值:成功返回格式化输出的字节数(不包括字符串的结尾'/0'),出错返回一个负值

printf格式化打印草标准输出,fprintf打印到制定文件的stream中,sprintf并不打印文件,而是打印到用户提供的缓冲区str中并在末尾加’/0’,snprintf的size参数制定缓冲区长度,如果超过长度就截断

后面四个函数在前面四个函数前加了个v,表示可变参数不是以…的形式传进来,而是以va_list传进来

#include <stdio.h>

int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

#include <stdarg.h>

int vscanf(const char *format, va_list ap);
int vsscanf(const char *str, const char *format, va_list ap);
int vfscanf(FILE *stream, const char *format, va_list ap);
返回值:返回成功匹配和赋值的参数个数,成功匹配的参数可能少于所提供的赋值参数,返回0表示一个都不匹配,出错或者读到文件或字符串末尾时返回EOF并设置errno

scanf从标准输入读字符串,按格式化字符串format中转换说明解释这些字符,转换后赋给后面参数,fscanf从指定的文件stream中读字符,sscanf从制定的字符串str中读字符

C标准库的I/O缓冲区

用户调用C标准I/O库函数读写文件或设备,而这些库函数要通过系统调用把读写请求传给内核,最终由内核驱动设备完成I/O操作.

标准库的I/O缓冲区

Happy Study Linux 2 - C标准库

C标准库I/O缓冲区三种类型:

全缓冲

如果缓冲区写满了就回内核,常规文件通常都是全缓冲

行缓冲

如果用户程序写的数据中由换行符就把这一行写回内核,标准输入和输出是行缓冲

无缓冲

用户程序每次调用库函数读写操作都通过系统写回内核,标准错误输出是无缓冲

数值字符串转换函数

int atoi(const char *nptr);
double atof(const char *nptr);
返回值:转换结果

atoi将一个字符串开头可以识别成十进制整数的部分转成int类型

atof把一个字符串开头可以识别成浮点数的部分转换成double

分配内存的函数

除了malloc之外,C标准库还提供两个在堆空间分配内存的函数,分配的空间都由free释放

void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
返回值:成功返回所分配内存空间的首地址,出错返回NULL

calloc,分配nmemb个元素的内存空间,每个元素占size个字节

realloc函数简化了malloc分配空间,讲数据转移,释放内存空间这些步骤,讲原内存空间的指针ptr传给realloc,通过size制定新大小,返回新空间首地址,并释放原内存空间.

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址