C 语言标准库函数
函数声明 | 说明 | 注意 | 安全性 |
---|---|---|---|
int getc(FILE *stream); |
getc 与 fgetc 几乎一致,区别在于 getc 为宏,fgetc 为函数,一般来说宏产生较大的代码,但是避免了函数调用的堆栈操作,所以速度会比较快,而宏展开可能对其参数有不止一次的调用,为了保险起见不能使用带有 side effects 的参数,由此可见使用 fgetc 比 getc 要安全。 | side effects | ⚠️ |
int getchar(void); |
调用时如果 stdin 内有字符,则取出 stdin 中的第一个字符返回;否则阻塞等待用户输入,直到用户输入 '\n' 或者 ^D (EOF) 停止输入(flush),'\n' 会插入到 stdin 中,EOF 不会插入到 stdin 中,若此时 stdin 内有字符,则取出 stdin 中的第一个字符返回,否则返回 EOF (-1) 。相当于 getc(stdin)。 | - | ✅ |
int fgetc(FILE *stream); |
见 getc。 | - | ✅ |
char *gets(char *s); |
若 stdin 为空,等待用户输入,直到用户输入 '\n' 或 ^D (EOF) 停止输入(flush),<u>'\n' 会被换成空字符 '\0'</u>,stdin 的 str 和 '\0' 流入缓冲区 s,如果 strlen(str) 大于 sizeof(s) 会破坏程序堆栈导致程序崩溃,如果调用成功则返回缓冲区指针 s。Never use this function! | 缓冲区溢出 | ❌ |
char *fgets(char *s, int size, FILE *stream); |
若 stdin 为空,等待用户输入,直到用户输入 '\n' 或 ^D (EOF) 停止输入(flush),'\n'会插入到 stdin 中,EOF 不会插入到 stdin 中,stdin 流入缓冲区 s 的字符数最多为 size-1 个,自动在第 size 个位置补上 '\0',共 size 个字符。如果 size > sizeof(s),当 stdin 含有足够多字符时会破坏程序堆栈导致程序崩溃。所以最好取值 size=sizeof(s),即等于缓冲区大小。fgets 比 gets 要安全。 | size 不能大于缓冲区s大小 | ⚠️ |
int putc(int c, FILE *stream); |
putc 与 fputc 几乎一致,区别在于 putc 为宏,fputc 为函数,一般来说宏产生较大的代码,但是避免了函数调用的堆栈操作,所以速度会比较快,而宏展开可能对其参数有不止一次的调用,为了保险起见不能使用带有 side effects 的参数,由此可见使用 fputc 比 putc 要安全。 | side effects | ⚠️ |
int putchar(int c); |
相当于 putc(c, stdout)。 | - | ✅ |
int fputc(int c, FILE *stream); |
见 putc。 | - | ✅ |
int puts(const char *s); |
将字符串 s 写入到 stdout,<u>'\0' 会被换成 '\n'并写入</u>。 | - | ✅ |
int fputs(const char *s, FILE *stream); |
将字符串 s 写入到 stream。 | - | ✅ |
int scanf(const char *format, ...); |
从 stdin 格式化读取数据。 | - | ✅ |
int fscanf(FILE *stream, const char *format, ...); |
从 stream 格式化读取数据。 | - | ✅ |
int sscanf(const char *str, const char *format, ...); |
从字符串数组 str 格式化读取数据。 | - | ✅ |
int printf(const char *format, ...); |
格式化字符串输出到 stdout。 | - | ✅ |
int fprintf(FILE *stream, const char *format, ...); |
格式化字符串输出到 stream。 | - | ✅ |
int sprintf(char *str, const char *format, ...); |
格式化字符串复制到缓冲区 str(字符串数组)中,如果格式化字符串长度大于 sizeof(str) 即缓冲区大小,会破坏程序堆栈导致程序崩溃。 | 缓冲区溢出 | ❌ |
int snprintf(char *str, size_t size, const char *format, ...); |
与 sprintf 类似,但是可以指定 size 从格式化字符串最多取前 size-1 个字符加一个空字符 '\0' 复制到缓冲区 str。应取值 size = sizeof(str)。 | size 不能大于缓冲区str的大小 | ⚠️ |
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream); |
从 stream 读取最多 nmemb 个(每个 size 字节大小)数据项存储到缓冲区 ptr 。如果缓冲区 ptr 不足够大,可能会发生缓冲区溢出。如果调用成功则返回读取到的数据项个数。 | size 和 nmemb 的取值大小 | ⚠️ |
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); |
将缓冲区 ptr 中 nmemb 个 (每个 size 字节大小)数据项写入到 stream。如果调用成功则返回写入成功的数据项个数。 | - | ✅ |
Linux 系统调用
函数声明 | 说明 | 注意 | 安全性 |
---|---|---|---|
ssize_t read(int fd, void *buf, size_t count); |
从文件 fd 中取最多 count 个字符存放在缓冲区 buf 中。该函数的返回值为读取到的字节数。如果 count > sizeof(buf) 可能发生缓冲区溢出。 | cout 的取值大小 | ⚠️ |
ssize_t write(int fd, const void *buf, size_t count); |
将缓冲区 buf 中 count 个字节写入到文件 fd。 | - | ✅ |
更新:
fgets: On linux Ctrl-D only works when the buffer is already empty otherwise it just flushes it. Therefore unless you have pressed enter without any characters after that, you will have to press Ctrl-D twice.
网友评论