IO进程学习day1

一.系统调用和库函数的区别

  二.常用的标准IO和系统调用

 三.文件结构体(FILE)

1> 关于ctags的使用

作用:追代码使用

使用方式:

1、在指定目录下,使用指令ctags -R 创建一个索引文件

2、输入指令:vi -t 要查询的名字

3、可以使用ctrl + ]: 继续往后追,使用ctrl+[ :回退

2> 追FILE结构体的步骤:

1、进入根目录的usr目录中的include目录下

2、使用指令:ctags -R 创建索引文件

3、输入指令:vi -t FILE 开始追该结构体

 

 

 

 

 

文件结构体

struct _IO_FILE {                                                                                                                          


257   char* _IO_buf_base;   /* 缓冲区开始位置 */
258   char* _IO_buf_end;    /* 缓冲区结束位置 */


267 
268   int _fileno;         //文件描述符
   }

特殊的文件指针(无需定义)

1> stdin:标准输入文件指针(scanf) ---->对应的文件描述符:0

2> stdout:标准输出指针(printf) ---->对应的文件描述符:1

3> stderr:标准出错指针 ---->对应的文件描述符:2

 FIFE *fopen

 #include <stdio.h>

FILE *fopen(const char *pathname, const char *mode);

功能:打开给定路径的文件,以mode的形式打开

参数1: 要打开的文件的路径,是一个字符串

参数2:打开文件时的打开方式,是一个字符串

r 以只读的形式打开一个文件,文件指针定位在开头 Open text file for reading. The stream is positioned at the beginning of the file.

r+ 以读写的形式打开一个文件,文件指针定位在开头 Open for reading and writing. The stream is positioned at the beginning of the file.

w 以只写的形式打开文件,如果文件不存在则创建文件,如果文件存在则清空文件内容,文件指针定位在开头 Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.

w+ 以读写的形式打开文件,如果文件不存在则创建文件,如果文件存在则清空文件内容,文件指针定位在开头 Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file.

a 以追加的形式打开文件(结尾写),如果文件不存在则创建文件,如果存在则结尾写,文件指针定位在结尾 Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file.

a+ 以读或追加的形式打开文件,如果文件不存在,则创建文件,读指针定位在开头,写指针定位在结尾 Open for reading and appending (writing at end of file). The file is created if it does not exist. The initial file posi‐ tion for reading is at the beginning of the file, but output is always appended to the end of the file. 返回值:成功打开文件,返回该文件的地址,失败返回NULL,并置位错误码

打开文件代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char *argv[])
{
	FILE *fp=NULL;//定义一个文件指针
//	fp=fopen("./01text.txt","r");//只读文件必须存在
	fp=fopen("./01text.txt","r+");
//	fp=fopen("./01text.txt","w");//只写
//	fp=fopen("./01text.txt","w+");
//	fp=fopen("./01text.txt","a");//追加
//	fp=fopen("./01text.txt","a+");

	if(NULL==fp)
	{
		printf("文件打开失败\n");
		return -1;
	}
	else
	{
		printf("打开成功\n");
	}
	return 0;
}

运行结果 

 man手册

关闭文件(fclose)

#include <stdio.h> int fclose(FILE *stream);
功能:刷新文件缓冲区,并关闭文件描述符
参数:要关闭的文件指针
返回值:成功返回0,失败返回EOF并置位错误码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char *argv[])
{
	FILE *fp=NULL;//定义一个文件指针
//	fp=fopen("./01text.txt","r");//只读文件必须存在
//	fp=fopen("./01text.txt","r+");
//	fp=fopen("./01text.txt","w");//只写
//	fp=fopen("./01text.txt","w+");
//	fp=fopen("./01text.txt","a");//追加
//	fp=fopen("./01text.txt","a+");

	if(NULL==fp)
	{
		printf("文件打开失败\n");
		return -1;
	}
	else
	{
		printf("打开成功\n");
	}
	fclose(fp);//关闭文件夹
	return 0;
} 

man fclose 

 错误码:错误码是在文件IO或标准IO调用相关接口函数时,如果出现错误,那么内核层就会向用户层传递一个错误信息,每个错误码对应的错误信息不同

man 错误码:

 

 

 

 处理错误码的两个函数

#include <string.h>
char *strerror(int errnum);
功能:将给定的错误码,转变成对应的字符串信息
参数:错误码
返回值:成功返回错误码的信息,失败返回“Unknown error nnn”
注意:这里面用到了errno,该错误码定义在:#include<errno.h>头文件中
#include <stdio.h>
void perror(const char *s);
功能:当错误码更新时,可以使用该函数,该函数会将错误码信息输出,并附上一个提示信息s,自动换行
参数:提示信息,是一个字符串
返回值:无
#include <stdio.h>
#include <stdlib.h>
#include <string.h>//strerror函数对应的头文件
#include<errno.h>
int main(int argc, const char *argv[])
{
	FILE *fp=NULL;//定义一个文件指针
//	fp=fopen("./01text.txt","r");//只读文件必须存在
	fp=fopen("./01text.txt","r+");
//	fp=fopen("./01text.txt","w");//只写
//	fp=fopen("./01text.txt","w+");
//	fp=fopen("./01text.txt","a");//追加
//	fp=fopen("./01text.txt","a+");

	if(NULL==fp)
	{
		printf("文件打开失败\n");
		printf("%d\n",errno);
		printf("%s\n",strerror(errno));//输出错误码对应的错误信息
		return -1;
	}
	else
	{
		printf("打开成功\n");
	}
	fclose(fp);//关闭fp指针打开的文件
	return 0;
} 

 

 

 成功打开也有错误码,对应succses

字符的输入输出(fgetc、fputc)

1> fputc函数

#include <stdio.h>

int fputc(int c, FILE *stream); //fputc('H', fp)

功能:将给定的字符,写入到指定的文件中去

参数1:要写入的字符,以unsigned char形式写入

参数2:要写入的文件

返回值:成功返回写入的字符的ascii值,失败返回EOF



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<errno.h>
int main(int argc, const char *argv[])
{
	//定义文件指针并打开文件
	FILE *fp;
	if((fp=fopen("./test.txt","w"))==NULL)
	{
	perror("fopen error");
			return -1;
	}
	//将数据写入文件
	fputc('h',fp);
	fputc('e',fp);
	fputc('l',fp);
	fputc('l',fp);
	fputc('o',fp);
	fputc('!',fp);

	//关闭文件夹
	fclose(fp);

	return 0;
}

 

 

字符串输入函数:fgets

#include <stdio.h>

char *fgets(char *s, int size, FILE *stream);

功能:从stream指针指向的文件中读取最多长度为size-1的字符串,放入数组s中

参数1:字符串容器

参数2:读取的长度:最多为size-1,如果遇到新的一行或者EOF会结束一次读取,并且会将换行作为字符放入数组中,并在最后放入字符串结束标志'\0'

参数3:文件指针 返回值:成功返回读取的字符串的地址,失败返回NULL

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<errno.h>
int main(int argc, const char *argv[])
{
	//定义文件指针并打开文件
	FILE *fp;
	if((fp=fopen("./test.txt","r"))==NULL)
	{
	perror("fopen error");
			return -1;
	}
	//从文件中读取数据
	char buf;
	while((buf=fgetc(fp))!=EOF)
	{
		printf("%c\t",buf);
	}
		//关闭文件夹
	fclose(fp);

	return 0;
}

 

 

练习:

1> 使用fgetc来统计一下给定文件的行号

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char *argv[])
{
    //argc是外部传参的参数个数
    //argv:是一个字符串指针数组,表示的是传入参数字符串的地址
    if(argc != 2)
    {
        printf("input file error\n");
        printf("usage:./a.out fileName\n");
        return -1;
    }

    //定义文件指针
    FILE *fp;
    //以只读的形式打开文件
    if((fp=fopen(argv[1], "r")) == NULL)
    {
        perror("fopen error");
        return -1;
    }

    //读取文件中的字符,并判断是否为换行
    char buf;
    int count = 0;          //记录行数
    while((buf=fgetc(fp)) != EOF)
    {
        //对buf进行判断
        if(buf == '\n')
        {
            count++;
        }
    }

    //关闭文件
    fclose(fp);

    printf("您给的文件一共有%d行\n", count);

    return 0;
}

 

 使用fgetc和fputc完成两个文件内容的拷贝工作

#include<myhead.h>

int main(int argc, const char *argv[])
{
    //判断是否传入两个文件
    if(argc != 3)
    {
        printf("intput file error\n");
        printf("usage: ./a.out srcfile dstfile\n");
        return -1;
    }

    //以只读的形式打开源文件
    FILE *srcfp;
    if((srcfp = fopen(argv[1], "r")) == NULL)
    {
        perror("srcfile open error");
        return -1;
    }

    //以只写的形式打开目标文件
    FILE *dstfp;
    if((dstfp=fopen(argv[2], "w")) == NULL)
    {
        perror("dstfile open error");
        return -1;
    }

    //定义搬运工
    char buf;
    while((buf=fgetc(srcfp)) != EOF)
    {
        //将数据写入目标文件中
        fputc(buf, dstfp);
    }

    //关闭文件指针
    fclose(srcfp);
    fclose(dstfp);

    printf("拷贝成功\n");

    return 0;
}

 

字符串输入输出(fgets、fputs)

1> 字符串输出函数:fputs

#include <stdio.h>

int fputs(const char *s, FILE *stream);

功能:将指定的字符串,输出到指定的文件中

参数1:要输出的字符串

参数2:要被写入的文件指针

返回值:成功返回写入文件中字符的个数,失败返回EOF

 

2>字符串输入函数:fgets

#include <stdio.h>

char *fgets(char *s, int size, FILE *stream);

功能:从stream指针指向的文件中读取最多长度为size-1的字符串,放入数组s中

参数1:字符串容器

参数2:读取的长度:最多为size-1,如果遇到新的一行或者EOF会结束一次读取,并且会将换行作为字符放入数组中,并在最后放入字符串结束标志'\0'

#include<myhead.h>

int main(int argc, const char *argv[])
{
    //定义文件指针
    FILE *fp;
    //以只写的形式打开文件
    if((fp=fopen("./08test.txt", "w+")) == NULL)
    {
        perror("fopen error");
        return -1;
    }

    //向文件中写入一个字符串
    fputs("Good Good Study\n", fp);
    fputs("Day Day Up\n", fp);

    //关闭文件
    fclose(fp);

    //以只读的形式打开文件
    if((fp=fopen("./08test.txt", "r")) == NULL)
    {
        perror("fopen error");
        return -1;
    }

    //定义一个buf
    char buf[5];
    while(fgets(buf, sizeof(buf), fp) != NULL)
    {
        printf("%s", buf);
        printf("111111111111111111111111111\n");
    }
    //关闭文件
    fclose(fp);

    return 0;
}

参数3:文件指针 返回值:成功返回读取的字符串的地址,失败返回NULL

关于缓冲区大小问题

1> 行缓存:和终端相关的文件的缓冲区(stdin、stdout),大小为1024字节

2> 全缓存:和文件操作相关的文件缓冲区(fp),大小为4096字节

3> 不缓存:和出错相关的文件缓冲区,是没有缓冲区的(stderr),大小为0

课后作业:

1.使用fgets完成求一个文件的行号

#include <stdio.h>

int main() {
    char filename[256];
    printf("请输入文件名:");
    scanf("%s", filename);

    FILE *file = fopen(filename, "r");
    if (file == NULL) {
        printf("无法打开文件。\n");
        return 1;
    }

    char line[256];
    int line_count = 0;

    while (fgets(line, sizeof(line), file) != NULL) {
        line_count++;
        // 在此处处理每行的内容,如果不需要处理可以跳过该步骤
    }

    printf("文件总共有 %d 行。\n", line_count);

    fclose(file);

    return 0;
}

运行结果:

2. 使用fgets、fputs完成两个文件的拷贝

#include <stdio.h>

int main() {
    char source_filename[256];
    char destination_filename[256];

    printf("请输入源文件名:");
    scanf("%s", source_filename);
    printf("请输入目标文件名:");
    scanf("%s", destination_filename);

    FILE *source_file = fopen(source_filename, "r");
    if (source_file == NULL) {
        printf("无法打开源文件。\n");
        return 1;
    }

    FILE *destination_file = fopen(destination_filename, "w");
    if (destination_file == NULL) {
        printf("无法创建目标文件。\n");
        fclose(source_file);
        return 1;
    }

    char buffer[256];

    while (fgets(buffer, sizeof(buffer), source_file) != NULL) {
        fputs(buffer, destination_file);
    }

    printf("文件拷贝完成。\n");

    fclose(source_file);
    fclose(destination_file);

    return 0;
}

效果图

 思维导图

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值