新增韦东山文件IO内容

This commit is contained in:
lzy
2024-05-01 16:15:35 +08:00
parent 5399da7488
commit 3ed46aa29f
6 changed files with 266 additions and 10 deletions

View File

@@ -33,8 +33,8 @@ FILE *fopen(const char *path, const char *mode);
*/
int fclose(FILE *fp);
int fputc(FILE *stream);
int fgetc(int c, FILE *stream);
int fputc(int c, FILE *stream);
int fgetc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);
/**
@@ -64,8 +64,6 @@ 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, ...);
/**
@@ -146,9 +144,10 @@ fflush();
/**
* @prarm: mode
* _IONBF
* _IOLBF
* _IOFBF
* 三种缓冲模式:
* _IONBF
* _IOLBF
* _IOFBF
*/
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
@@ -200,13 +199,40 @@ FILE *tmpfile(void);
- write
- lsee
可以使用`./open file &`来后台运行一个程序。
然后通过`ps`查看进程号
然后进入`/proc/进程号/fd`查看文件描述符
前三个是标准输入输出错误,后面的是打开的文件描述符
```c
/**
* flag:
*
* r -> O_RDONLY
* r+ -> O_RDWR
* w -> O_WRONLY | O_CREAT | O_TRUNC
* w+ -> O_RDWR | O_TRUNC | O_CREAT
*
* O_RDONLY 只读
* O_WRONLY 只写
* O_RDWR 读写
* O_CREAT 创建
* O_TRUNC 截断
* O_APPEND 追加
* O_EXCL 排他(若要创建的文件已存在则报错)
* O_NONBLOCK 非阻塞
* O_SYNC 同步
* O_DSYNC 数据同步
* O_RSYNC 读同步
* O_DIRECT 直接IO
* O_LARGEFILE 大文件
* O_DIRECTORY 目录
* O_NOFOLLOW 不跟踪符号链接
* O_CLOEXEC close-on-exec
* O_PATH 仅打开目录
* O_TMPFILE 临时文件
* O_NOCTTY 不分配控制终端
*
* 如果有creat就必须用三参数的形式
* C语言没有重载这是变参函数
@@ -214,6 +240,7 @@ FILE *tmpfile(void);
* @prarm: pathname 文件路径
* @prarm: flags 文件打开方式
* @prarm: mode 文件权限
* 假如0666就是rw-rw-rw-110110110
*
*/
int open(const char *pathname, int flags);
@@ -222,14 +249,12 @@ int open(const char *pathname, int flags, mode_t mode);
int close(int fd);
/**
* read from a file descriptor
*
* @return 读取的字节数,失败返回-1
*/
ssize_t read(int fd, void *buf, size_t count);
/**
* write to a file descriptor
* 想要控制写入的位置需要使用lseek
*
* @return 写入的字节数,失败返回-1
*/
@@ -248,6 +273,16 @@ off_t lseek(int fd, offt offset, int whence);
```
### 例题通过文件IO处理csv表格
```csv
,语文,数学,英语,总分,评价
张三,90,91,92,,
李四,80,81,82,,
王五,70,71,72,,
```
思路:逐行处理
可以使用16进制查看工具
### 文件IO与标准IO的区别
区别:响应速度&吞吐量

View File

@@ -0,0 +1,205 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#if 1
# define debug(fmt, args...) printf(fmt, ##args)
#else
# define debug(fmt, args...)
#endif
/**
* @brief 读取一行
* @details
* 循环读入一个字符
* 如何判断读完一行? 读到0x0d, 0x0a
*
* @param fd
* @param buf
*
* @return int 读到的一行数据的数据个数( n>=0 )
* -1: 读到文件尾部或者出错
*/
static int read_line(int fd, unsigned char *buf)
{
unsigned char c;
int len;
int i = 0;
int err = 0;
while (1)
{
len = read(fd, &c, 1);
if (len <= 0)
{
err = -1;
break;
}
else
{
if (c != '\n' && c != '\r')
{
buf[i] = c;
i++;
}
else /* 碰到回车换行 */
{
err = 0;
break;
}
}
}
buf[i] = '\0';
if (err && (0 == i))
/* 读到文件尾部且无有效数据 */
return -1;
else
return i;
}
/**
* @brief 处理一行的数据, 计算出总分和评价
* @details
*
* @param data_buf
* @param result_buf
*
* @return int
*/
static void process_data(unsigned char *data_buf, unsigned char *result_buf)
{
/**
* eg1: data_buf=",语文,数学,英语,总分,评价"
* result_buf=",语文,数学,英语,总分,评价"
*
* eg2: data_buf="张三,90,91,92,,"
* result_buf="张三,90,91,92,273,A+"
*
*/
char name[100];
int scores[3];
int sum;
char *levels[] = {"A+", "A", "B"};
int level;
// debug("data_buf[0]: %x\n", data_buf[0]);
if (0xef == data_buf[0]) /* 对于UTF-8, 前三个字符是0xef 0xbb 0xbf */
{
strcpy(result_buf, data_buf);
}
else
{
// debug("data_buf: %s\n", data_buf);
// debug("进入了\n");
/**
* @brief 从字符串得到数据
* @details
* 拆分信息: scanf分隔符
* %[^,]: 读数据直到碰到逗号
*
*/
sscanf(data_buf,
"%[^,],%d,%d,%d,,",
name,
&scores[0],
&scores[1],
&scores[2]);
debug("name: %s, scores: %d, %d, %d\n",
name,
scores[0],
scores[1],
scores[2]);
sum = scores[0] + scores[1] + scores[2];
if (sum >= 270)
level = 0;
else if (sum >= 240)
level = 1;
else
level = 2;
sprintf(result_buf,
"%s,%d,%d,%d,%d,%s",
name,
scores[0],
scores[1],
scores[2],
sum,
levels[level]);
}
}
/**
* @brief 处理csv表格
* @details
* Usage: ./W_process_excel data.csv result.csv
*
* @param argc
* @param argv
*
* @return int
*/
int main(int argc, char **argv)
{
int fd_data, fd_result;
int len;
unsigned char data_buf[1000];
unsigned char result_buf[1000];
if (argc != 3)
{
printf("Usage: %s data.csv result.csv\n", argv[0]);
exit(1);
}
fd_data = open(argv[1], O_RDONLY);
if (fd_data < 0)
{
perror("open data.csv");
exit(1);
}
else
printf("data file fd: %d\n", fd_data);
fd_result = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd_result < 0)
{
perror("open result.csv");
exit(1);
}
else
printf("result file fd: %d\n", fd_result);
while (1)
{
/* 读取1行 */
len = read_line(fd_data, data_buf);
if (-1 == len)
break;
// if (len != 0)
// debug("%s\n\r", data_buf);
if (len != 0)
{
/* 处理1行 */
process_data(data_buf, result_buf);
/* 写入结果文件 */
write(fd_result, result_buf, strlen(result_buf));
write(fd_result, "\r\n", 2);
}
}
close(fd_data);
close(fd_result);
exit(0);
}

View File

@@ -0,0 +1,4 @@
,语文,数学,英语,总分,评价
张三,90,91,92,,
李四,80,81,82,,
王五,70,71,72,,
1 语文 数学 英语 总分 评价
2 张三 90 91 92
3 李四 80 81 82
4 王五 70 71 72

View File

@@ -0,0 +1,4 @@
,语文,数学,英语,总分,评价
张三,90,91,92,273,A+
李四,80,81,82,243,A
王五,70,71,72,213,B
1 语文 数学 英语 总分 评价
2 张三 90 91 92 273 A+
3 李四 80 81 82 243 A
4 王五 70 71 72 213 B