主要设计了write函数,printf函数以及lseek函数的详细解析。并且通过实例进行分析。涉及实例:设计一个简单的学生信息录入系统,实现在终端输入学生的不同信息,并且将信息写入到文件中,最后可以自由控制跳出。
NAME
write -在一个文件描述符上执行写操作
概述
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
描述
write 向文件描述符 fd 所引用的文件中写入 从 buf 开始的缓冲区中 count 字节的数据. POSIX规定,当使用了write()之后再使用 read(),那么读取到的应该是更新后的数据. 但请注意并不是所有的文件系统都是 POSIX兼容的.
返回值
成功时返回所写入的字节数(若为零则表示没有写入数据). 错误时返回-1,并置errno为相应值. 若count为零,对于普通文件无任何影响,但对特殊文件 将产生不可预料的后果.
使用write()向文件里面写内容
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include<sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
//1. open the file
int fd =open("./1.txt",O_RDWR|O_CREAT,0664);//读写-创建,权限
if(-1 == fd)
{
perror("open 1.txt error");
return -1;
}
//2.operate the file--write
char buf[1024]={0};
//写入的内容
char * ptr ="我是lihuining\n";//注意写入的文件的格式,但是是文本文件,所以随便
int w =write(fd,ptr,strlen(ptr));
int r = read(fd,buf,strlen(ptr));
if (-1==r)
{
perror("read error");
return -2;
}
if (strlen(ptr)!=w)//至少丢了一个字节也是错的--严谨性
{
perror("write error");
return -2;
}
printf("%s\n",buf);//%s must find the \o in the fnal byte
//close the file
close(fd);
return 0;
}
使用文件相关的命令,设计一个简单的学生信息录入系统,实现在终端输入学生的不同信息,并且将信息写入到文件中,最后可以自由控制跳出。
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
int fd = open("./1.txt", O_RDWR | O_CREAT|O_APPEND, 0664);
if (-1 == fd) {
perror("open 1.txt error");
return -1;
}
char buf[1024] = {0};
char name[256], xuehao[256], age[256], add[256];
char choice;
do {
printf("请你输入你的姓名: ");
scanf("%s", name);
printf("\n");
printf("请你输入你的学号: ");
scanf("%s", xuehao);
printf("\n");
printf("请你输入你的年龄: ");
scanf("%s", age);
printf("\n");
printf("请你输入你的地址: ");
scanf("%s", add);
printf("\n");
strcat(name, " ");
strcat(name, xuehao);
strcat(name, " ");
strcat(name, age);
strcat(name, " ");
strcat(name, add);
strcat(name, "\n"); // 添加换行符以区分不同人的信息
int w = write(fd, name, strlen(name));
if (strlen(name) != w) {// 严谨性检查
perror("write error");
exit(2);//直接退出
}
printf("是否继续输入信息?(y/n): ");
scanf(" %c", &choice); // 注意前面的空格,这样可以消耗掉之前的换行符或其他空白字符
printf("\n");
} while (choice == 'y' || choice == 'Y');
lseek(fd, 0, SEEK_SET); 重新定位到文件开始位置
int r = read(fd, buf, sizeof(buf) - 1);// 确保buf有足够的空间,并留出一个字节来添加'\0'
if (-1 == r) {
perror("read error");
return -2;
}
buf[r] = '\0';// 添加字符串结束符
printf("所有信息:\n%s\n", buf);
//关闭文件
close(fd);
return 0;
}
需要注意的一点就是int fd = open("./1.txt", O_RDWR | O_CREAT|O_APPEND, 0664);
这一行的命令我使用了O_APPEND
标志,该标志是让我们从默认的打开文件光标在文件开头
跳到光标在文件末尾
,所以上面代码我们可以多次执行,每次都可以在文件的末尾继续进行添加。
lseek
是一个系统调用,用于在文件中设置文件偏移量。它可以用来移动文件指针到文件的不同位置,从而实现随机访问文件。
lseek
函数的原型如下:
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
其中:
fd
:是一个文件描述符,表示已打开的文件。offset
:是一个偏移量,指定了文件指针相对于 whence
参数指定的位置的移动量。如果 whence
为 SEEK_SET
,则 offset
是从文件开始位置的偏移量;如果 whence
为 SEEK_CUR
,则 offset
是从当前文件指针位置的偏移量;如果 whence
为 SEEK_END
,则 offset
是从文件末尾的偏移量。whence
:指定了如何解释 offset
参数,可以是以下三个值之一:
SEEK_SET
:从文件开始位置开始偏移。SEEK_CUR
:从当前文件指针位置开始偏移。SEEK_END
:从文件末尾开始偏移。当你使用 lseek(fd, 0, SEEK_SET);
这样的调用时,它会将文件指针移动到文件的开始位置,因为 offset
为 0
,而 whence
为 SEEK_SET
。
这样,你可以重新定位文件指针,从而进行随机的文件读写操作。
在C语言中,printf
函数通常在接收到换行符 \n
或缓冲区满时才会刷新缓冲区并输出内容。这是因为标准输出(通常是屏幕)是行缓冲的。
当你调用 printf
时,输出内容首先被存储在一个缓冲区中。缓冲区的内容不会立即显示在屏幕上,而是等待一定的条件触发刷新。这些条件包括:
\n
。因此,如果你在 printf
中没有使用 \n
,并且缓冲区还没有满,那么输出内容不会立即显示在屏幕上。
为了立即显示输出内容,你可以:
printf
语句的末尾添加一个换行符 \n
。fflush(stdout);
刷新标准输出缓冲区。例如:
printf("Hello, World!\n"); // 添加了换行符
或者
printf("Hello, World!");
fflush(stdout); // 刷新缓冲区
这样,你就可以确保 printf
的输出立即显示在屏幕上。