一个简单的学生信息录入系统——write函数与lseek函数详细解析

2023-12-20 10:11:18

write函数与printf()函数详细解析

主要设计了write函数,printf函数以及lseek函数的详细解析。并且通过实例进行分析。涉及实例:设计一个简单的学生信息录入系统,实现在终端输入学生的不同信息,并且将信息写入到文件中,最后可以自由控制跳出。

一、 WRITE函数

1.1 WRITE 的基本用法

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为零,对于普通文件无任何影响,但对特殊文件 将产生不可预料的后果.

1.2 练习1 使用write()向文件里面写内容

使用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;
}


1.3 练习2 一个简单的学生信息录入系统

使用文件相关的命令,设计一个简单的学生信息录入系统,实现在终端输入学生的不同信息,并且将信息写入到文件中,最后可以自由控制跳出。

#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标志,该标志是让我们从默认的打开文件光标在文件开头跳到光标在文件末尾,所以上面代码我们可以多次执行,每次都可以在文件的末尾继续进行添加。

1.3.1 lseek函数解析

lseek 是一个系统调用,用于在文件中设置文件偏移量。它可以用来移动文件指针到文件的不同位置,从而实现随机访问文件。

lseek 函数的原型如下:

#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);

其中:

  • fd:是一个文件描述符,表示已打开的文件。
  • offset:是一个偏移量,指定了文件指针相对于 whence 参数指定的位置的移动量。如果 whenceSEEK_SET,则 offset 是从文件开始位置的偏移量;如果 whenceSEEK_CUR,则 offset 是从当前文件指针位置的偏移量;如果 whenceSEEK_END,则 offset 是从文件末尾的偏移量。
  • whence:指定了如何解释 offset 参数,可以是以下三个值之一:
    • SEEK_SET:从文件开始位置开始偏移。
    • SEEK_CUR:从当前文件指针位置开始偏移。
    • SEEK_END:从文件末尾开始偏移。

当你使用 lseek(fd, 0, SEEK_SET); 这样的调用时,它会将文件指针移动到文件的开始位置,因为 offset0,而 whenceSEEK_SET

这样,你可以重新定位文件指针,从而进行随机的文件读写操作。

二、printf()函数

在C语言中,printf 函数通常在接收到换行符 \n 或缓冲区满时才会刷新缓冲区并输出内容。这是因为标准输出(通常是屏幕)是行缓冲的。

当你调用 printf 时,输出内容首先被存储在一个缓冲区中。缓冲区的内容不会立即显示在屏幕上,而是等待一定的条件触发刷新。这些条件包括:

  1. 缓冲区满了。
  2. 遇到了换行符 \n
  3. 程序正常终止时,缓冲区的内容会被刷新。

因此,如果你在 printf 中没有使用 \n,并且缓冲区还没有满,那么输出内容不会立即显示在屏幕上。

为了立即显示输出内容,你可以:

  1. printf 语句的末尾添加一个换行符 \n
  2. 使用 fflush(stdout); 刷新标准输出缓冲区。

例如:

printf("Hello, World!\n"); // 添加了换行符

或者

printf("Hello, World!");
fflush(stdout); // 刷新缓冲区

这样,你就可以确保 printf 的输出立即显示在屏幕上。

文章来源:https://blog.csdn.net/qq_63831368/article/details/135098995
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。