From 808ec80a62a16a0b8ec80702b9d4dac87c770b18 Mon Sep 17 00:00:00 2001 From: lzy Date: Sat, 27 Apr 2024 00:22:26 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=BC=96=E7=A8=8B=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Chapter13/C13-Linux系统编程学习笔记.md | 148 ++++++++++++++++++++++--- Chapter13/io/stdio/atoi.c | 28 +++++ Chapter13/io/stdio/fflush.c | 20 ++++ Chapter13/io/stdio/fgetc.c | 32 ++++++ Chapter13/io/stdio/flen.c | 28 +++++ Chapter13/io/stdio/fopen.c | 2 + Chapter13/io/stdio/maxfopen.c | 32 ++++++ Chapter13/io/stdio/mycpy.c | 51 +++++++++ Chapter13/io/stdio/mycpy_fgets.c | 48 ++++++++ Chapter13/io/stdio/mycpy_fread.c | 50 +++++++++ 10 files changed, 426 insertions(+), 13 deletions(-) create mode 100644 Chapter13/io/stdio/atoi.c create mode 100644 Chapter13/io/stdio/fflush.c create mode 100644 Chapter13/io/stdio/fgetc.c create mode 100644 Chapter13/io/stdio/flen.c create mode 100644 Chapter13/io/stdio/maxfopen.c create mode 100644 Chapter13/io/stdio/mycpy.c create mode 100644 Chapter13/io/stdio/mycpy_fgets.c create mode 100644 Chapter13/io/stdio/mycpy_fread.c diff --git a/Chapter13/C13-Linux系统编程学习笔记.md b/Chapter13/C13-Linux系统编程学习笔记.md index 03bb552..cd930c1 100644 --- a/Chapter13/C13-Linux系统编程学习笔记.md +++ b/Chapter13/C13-Linux系统编程学习笔记.md @@ -14,23 +14,145 @@ /* stdio */ /* FILE类型贯穿始终 */ -FILE *fopen(const c); -fclose(); +FILE *fopen(const char *path, const char *mode); +/** + * fopen 返回指针的储存位置? 1.栈 2.静态区 3.堆 + * 正确答案:3.堆。 + * 因为如果是栈,就是函数内部局部变量,无法返回地址。 + * 如果是静态区,无法确定需要多少个这个变量。 + * + * 只有 r 和 r+ 一定要求文件存在 + * 另外几种不存在会创建 + * + * 创建文件的权限 + * 0666 & ~umask + * + * 对于普通用户 + * umask 得到 022 + * +*/ +int fclose(FILE *fp); -fgetc(); -fputc(); -fgets(); -fputs(); -fread(); -fwrite(); +int fputc(FILE *stream); +int fgetc(int c, FILE *stream); -printf(); -scanf(); +char *fgets(char *s, int size, FILE *stream); +/** + * 两种正常返回的情况: + * 1. 读了 size-1 个字节,最后一个字节留给 '\0' + * 2. 读到了 '\n' + * + * eg. 加入用fgets(buf, 5, stream) 来读 abcd + * 是会读两次的 + * 第一次:abcd'\0' + * 第二次:'\n''\0' +*/ +int fputs(const char *restrict s, FILE *restrict stream); -fseek(); -ftell(); -rewind(); +/** + * 这一对函数常用但是无法验证边界 + * 尽量一次只读单字节,更安全 + * + * 返回值:成功读/写的对象的数量 +*/ +size_t fread(void *ptr, size_t size, size_t nemmb, FILE *stream); +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); + +int printf(const char *restrict format, ...); +/** + * 常用于 fprintf(stderr,...) +*/ +int fprintf(FILE *restrict stream, const char *restrict format, ...); + +// TODO: +int dprintf(int fd, const char *restrict format, ...); + +/** + * 将格式化内容输出到一个字符串 + * + * 和 atoi() 正好相反 + * +*/ +int sprintf(char *restrict str, const char *restrict format, ...); + +/** + * 比sprintf多了size参数,更安全 +*/ +int snprintf(char str[restrict.size], + size_t size, + const char *restrict format, + ...) + +// !!! 慎用%s +int scanf(const char *restrict format, ...); +int fscanf(FILE *restrict stream, + const char *restrict format, ...); + + +/** + * 移动文件当前位置指针 + * + * 可用于生成空洞文件,下载器原理 + * + * @prarm: offset 移动多远 + * @prarm: whence 移动方向 + * SEEK_SET, SEEK_CUR, SEEK_END + * + * @return 成功0,失败-1 +*/ +int fseek(FILE *stream, long offset, int whence); + +/** + * 反映当前文件指针所在位置 + * + * 这个long的负值部分无法使用。 + * 所以文件无法超过2G。 + * +*/ +long ftell(FILE *stream); + +/** + * 解决上面long的问题。 + * + * 最好编译时加上 + * #define _FILE_OFFSET_BITS 64 + * 可以写入makefile + * + * 但是这俩函数是方言,前面那个long的一对支持C89,C99 + * +*/ +int fseeko(FILE *stream, off_t offset, int whence); +off_t ftello(FILE *stream); + +/** + * 将文件指针置于文件首 + * equivalent to: + * fseek(stream, 0L, SEEK_SET); +*/ +void rewind(FILE *stream); + +/** + * 缓冲区的作用: + * 大多数情况下是好事,合并系统调用 + * + * 行缓冲: 换行时候刷新,满了的时候刷新,强制刷新(标准输出是这样的,因为是终端设备) + * + * 全缓冲: 满了的时候刷新,强制刷新(默认,只要不是终端设备) + * + * 无缓冲: 如stderr,需要立即输出的内容 +*/ fflush(); + +/** + * @prarm: mode + * _IONBF + * _IOLBF + * _IOFBF +*/ +int setvbuf(FIEL *stream, char *buf, int mode, size_t size); + ``` + +P131 \ No newline at end of file diff --git a/Chapter13/io/stdio/atoi.c b/Chapter13/io/stdio/atoi.c new file mode 100644 index 0000000..b6f9b57 --- /dev/null +++ b/Chapter13/io/stdio/atoi.c @@ -0,0 +1,28 @@ +#include +#include + +int main(int argc, char **argv) +{ + char buf[1024]; + int year = 2014, month = 5, day = 13; + + printf("%d-%d-%d\n", year, month, day); + + sprintf(buf, "%d-%d-%d", year, month, day); + puts(buf); + +#if 0 + char str[] = "123456"; + + printf("%d\n", atoi(str)); + /** + * 输出 123456 + * + * 如果str是123a456 + * 输出123 + * + */ +#endif + + exit(0); +} \ No newline at end of file diff --git a/Chapter13/io/stdio/fflush.c b/Chapter13/io/stdio/fflush.c new file mode 100644 index 0000000..35f93c2 --- /dev/null +++ b/Chapter13/io/stdio/fflush.c @@ -0,0 +1,20 @@ +#include +#include + +int main(int argc, char **argv) +{ + int i; + + // 这里不加\n的话,什么都不输出 + // 要么加\n,要么fflush + printf("Before while()"); + fflush(stdout); + + while (1) + ; + + printf("After while()"); + fflush(NULL); + + exit(0); +} \ No newline at end of file diff --git a/Chapter13/io/stdio/fgetc.c b/Chapter13/io/stdio/fgetc.c new file mode 100644 index 0000000..7e04d6e --- /dev/null +++ b/Chapter13/io/stdio/fgetc.c @@ -0,0 +1,32 @@ +#include +#include + +int main(int argc, char **argv) +{ + FILE *fp; + int count; + + if (argc < 2) + { + fprintf(stderr, "Usage...\n"); + exit(1); + } + + fp = fopen(argv[1], "r"); + if (NULL == fp) + { + perror("fopen()"); + exit(1); + } + + while (EOF != fgetc(fp)) + { + count++; + } + + printf("count = %d", count); + + fclose(fp); + + exit(0); +} \ No newline at end of file diff --git a/Chapter13/io/stdio/flen.c b/Chapter13/io/stdio/flen.c new file mode 100644 index 0000000..791862a --- /dev/null +++ b/Chapter13/io/stdio/flen.c @@ -0,0 +1,28 @@ +#include +#include + +int main(int argc, char **argv) +{ + FILE *fp; + + if (argc < 2) + { + fprintf(stderr, "Usage...\n"); + exit(1); + } + + fp = fopen(argv[1], "r"); + if (NULL == fp) + { + perror("fopen()"); + exit(1); + } + + fseek(fp, 0, SEEK_END); + + printf("%d\n", ftell(fp)); + + fclose(fp); + + exit(0); +} \ No newline at end of file diff --git a/Chapter13/io/stdio/fopen.c b/Chapter13/io/stdio/fopen.c index 73f8f7b..5ad79c9 100644 --- a/Chapter13/io/stdio/fopen.c +++ b/Chapter13/io/stdio/fopen.c @@ -25,5 +25,7 @@ int main() puts("OK!"); + fclose(fp); + exit(0); } \ No newline at end of file diff --git a/Chapter13/io/stdio/maxfopen.c b/Chapter13/io/stdio/maxfopen.c new file mode 100644 index 0000000..fd2f77e --- /dev/null +++ b/Chapter13/io/stdio/maxfopen.c @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +int main() +{ + FILE *fp = NULL; + int count = 0; + + + while (1) + { + + fp = fopen("tmp", "w"); + if (NULL == fp) + { + perror("fopen()"); + break; + } + + count++; + } + + printf("count = %d\n", count); + // out: 4089 + /* 可以通过下面这个命令限制 */ + /* ulimit -n */ + /* 4096 */ + + exit(0); +} \ No newline at end of file diff --git a/Chapter13/io/stdio/mycpy.c b/Chapter13/io/stdio/mycpy.c new file mode 100644 index 0000000..34a6f32 --- /dev/null +++ b/Chapter13/io/stdio/mycpy.c @@ -0,0 +1,51 @@ +#include +#include + +/** + * @brief + * @details + * usage: ./mycpy + * + * @return int + */ + +int main(int argc, char **argv) +{ + FILE *fps, *fpd; + int ch; + + if (argc < 3) + { + fprintf(stderr, "Usage:%s \n", argv[0]); + exit(1); + } + + fopen(argv[1], "r"); + if (NULL == fps) + { + perror("fopen()"); + exit(1); + } + + fopen(argv[2], "w"); + if (NULL == fpd) + { + // !!! + fclose(fps); + perror("fopen()"); + exit(1); + } + + while (1) + { + ch = fgetc(fps); + if (EOF == ch) + break; + fputc(ch, fpd); + } + + fclose(fpd); + fclose(fps); + + exit(0); +} \ No newline at end of file diff --git a/Chapter13/io/stdio/mycpy_fgets.c b/Chapter13/io/stdio/mycpy_fgets.c new file mode 100644 index 0000000..774e2e7 --- /dev/null +++ b/Chapter13/io/stdio/mycpy_fgets.c @@ -0,0 +1,48 @@ +#include +#include + +#define BUFSIZE 1024 + +/** + * @brief + * @details + * usage: ./mycpy + * + * @return int + */ + +int main(int argc, char **argv) +{ + FILE *fps, *fpd; + char buf[BUFSIZE]; + + if (argc < 3) + { + fprintf(stderr, "Usage:%s \n", argv[0]); + exit(1); + } + + fopen(argv[1], "r"); + if (NULL == fps) + { + perror("fopen()"); + exit(1); + } + + fopen(argv[2], "w"); + if (NULL == fpd) + { + // !!! + fclose(fps); + perror("fopen()"); + exit(1); + } + + while (NULL != fgets(buf, BUFSIZE, fps)) + fputs(buf, fpd); + + fclose(fpd); + fclose(fps); + + exit(0); +} \ No newline at end of file diff --git a/Chapter13/io/stdio/mycpy_fread.c b/Chapter13/io/stdio/mycpy_fread.c new file mode 100644 index 0000000..a09fbaf --- /dev/null +++ b/Chapter13/io/stdio/mycpy_fread.c @@ -0,0 +1,50 @@ +#include +#include + +#define BUFSIZE 1024 + +/** + * @brief + * @details + * usage: ./mycpy + * + * @return int + */ + +int main(int argc, char **argv) +{ + FILE *fps, *fpd; + char buf[BUFSIZE]; + int n; + + if (argc < 3) + { + fprintf(stderr, "Usage:%s \n", argv[0]); + exit(1); + } + + fopen(argv[1], "r"); + if (NULL == fps) + { + perror("fopen()"); + exit(1); + } + + fopen(argv[2], "w"); + if (NULL == fpd) + { + // !!! + fclose(fps); + perror("fopen()"); + exit(1); + } + + /* 用n接收读到的个数,因为不知道能不能正好读到BUFSIZE */ + while ((n = fread(buf, 1, BUFSIZE, fps)) > 0) + fread(buf, 1, n, fpd); + + fclose(fpd); + fclose(fps); + + exit(0); +}