【Linux】应用编程之C语言文件操作


前言

  对于文件IO来说,一切都是围绕文件描述符来进行的,在Linux系统中所有打开的文件都是一个对应的文件描述符。
  文件描述符的本质是一个非负整数,当我们打开一个文件时,系统会给我们分配一个文件描述符。
  当我们对一个文件做读写操作的时候,我们使用open函数的时候返回的就是这个文件的文件描述符,我们后续对文件的操作例如read和write都需要使用这个参数。

完成目标:
  在windows上编程和Linux上的文件操作有所不同(如果需要学习windows上的文件操作编程可以跳转到这里:C/C++文件读取操作),本文主要是熟悉Linux上的文件操作的接口使用和相关文档的翻译。


一、工程的创建

1、目录结构

在这里插入图片描述

2、Makefile

object = *.o
CC = gcc

main:$(object)
        $(CC) $(object) -o main
        rm *.o
        file main
%.o:%.c
        $(CC) -c $<
clean:
        rm *.o
        rm main

这里复制需要注意一下需要将复制过去的空格替换成TAB

二、文件的操作

1.创建、打开、关闭文件:open、close、creat

如需要查看函数的完整说明使用以下命令查看详细的说明;

man open 
man close  

下面是打开文件的函数接口以及使用该接口需要包含的头文件

// 使用系列操作需要包含得头文件
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>

// 文件操作的接口函数:我们常用的是open
 int open(const char *pathname, int flags); // 如果没有创建文件得权限使用该打开方式
 int open(const char *pathname, int flags, mode_t mode);// 如果打开文件发现没有得情况需要创建选项这里就需要填写mode权限

const char* pathname传入的是文件名的字符串地址
flags表示文件的打开方式,如下表

参数含义
O_CREAT必要时创建文件
O_TRUNC删除全部现有数据
O_APPEND维持现有数据,保存到其后面
O_RDONLY只读打开
O_WRONLY只写打开
O_RDWR读写打开

第二个函数还提供一个mode_t的参数该参数是表示创建文件的权限设置,这里类似chmod指令,在commod下使用ls -al 或则 ll指令可以查看文件权限

-rw-rw-r-- 1 stylle stylle  291 May 24 10:36 file.c
-rwxrwxr-x 1 stylle stylle 8384 May 24 10:16 main
-rw-rw-r-- 1 stylle stylle  129 May 24 10:03 Makefile

r表示可读 -4
w表示可写 - 2
x表示可执行 -1

所以我们常用到得chmod 777 就表示将该文件赋予可读可写可执行得权限;我们在操作完文件过后一定要释放文件,所以我们open过后一定要跟close函数,就如同malloc和free一样;

#include <unistd.h>

int close(int fd); // 直接传入我们刚刚open函数返回的文件描述符

完整的使用用例

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char **argv)
{
        int fd;
        fd = open("file_tmp.c", O_CREAT | O_RDWR,0666);
        if(fd < 0)
        {
                perror("open file error\r\n");
        }
        else{
                printf("fd = %d\r\n",fd);
                close(fd);
        }
        return 0;
}

在这里插入图片描述

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int creat(const char *pathname, mode_t mode);

pathname为创建文件的名称
mode表示创建文件的权限

返回的参数为创建的文件描述符,如果小于0表示文件创建失败,下面是程序演示

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
	int fd;

	if(argc < 2)
	{
		perror("plese input creat filename\r\n");
		exit(0);
	}

	int ret = creat(argv[1], 0666);
	if(ret < 0)
	{
		perror("creat file error\r\n");
		exit(0);
	}
	printf("creat file %s success\r\n",argv[1]);

	return 0;
}

在这里插入图片描述

2.读取、写入文件:read、write

然后我们开始向文件中写入内容然后从中读取出来,这里我们需要使用到write和read,然后我们查看函数需要传入的参数

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);

write
fd表示文件描述符,这里填写我们open函数返回的fd就可以了
buf表示要写入文件的字符串
count表示要写入字符的个数

read
fd表示文件描述符,这里填写我们open函数返回的fd就可以了
buf表示接收读取到的字符串
count表示要读取的字符个数

然后我们来实验一下

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv)
{
	int fd;
	char read_str[15];
	int ret = 0;

	fd = open("tmp.txt", O_CREAT | O_RDWR,0666);
	if(fd < 0)
	{
		perror("open file error\r\n");
		exit(0);
	}
	ret = write(fd, "hello world", strlen("hello world")+1);// +1是strlen未包含‘\0’的长度
	if(ret < 0)
	{
		perror("write error\r\n");
	}
	close(fd);

	fd = open("tmp.txt", O_RDONLY);
	if(fd < 0)
	{
		perror("open read only file error\r\n");
		exit(0);
	}

	ret = read(fd, read_str, ret);
	close(fd);

	if(ret < 0)
	{
		perror("read error\r\n");
	}
	else
	{
		printf("read_num = %d read:%s\r\n",ret,read_str);	
	}

	return 0;
}

在这里插入图片描述

3.文件定位:lseek

下面是打开文件的函数接口以及使用该接口需要包含的头文件

#include <sys/types.h>
#include <unistd.h>

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

fd 文件描述符
offset 文件指针位移位置如果为正整数表示向后位移如果为负整数表示向前位移
whence 一共有三个参数SEEK_SET、SEEK_CUR、SEEK_END分别表示从文件头、当前位置、文件尾开始位移

返回值为当前位移指针的位置,如果位移出错返回-1,下面来个小实验

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
	int fd;
	int ret;
	char read_str[10];

	fd = open("a.txt", O_RDONLY);
	if(fd < 0)
	{
		perror("open error");
		exit(0);
	}
	// a.txt: "hello stylle"
	ret = read(fd, read_str, 5);// read "hello"
	if(ret < 0)
	{
		perror("read error");
	}
	else
	{
		ret = lseek(fd, 0, SEEK_CUR);// return cur file addr
		read_str[5] = '\0';
		printf("read %d:%s\n",ret, read_str);
		
		ret = lseek(fd, 0, SEEK_END);
		printf("file size:%d\n",ret);

		lseek(fd, -7, SEEK_CUR);// '\0'
		memset(read_str, 0, 10);
		ret = read(fd, read_str, 6);
		if(ret > 0)
		{
			printf("read 6 digits:%s\n",read_str);
		}
		close(fd);
	}
	return 0;
}

在这里插入图片描述

最后

本章需要注意的点:
1、写入文件后不能马上读取需要重新打开读取
2、上述的内容并没有十分完整,完整函数的用法和原型可以使用man 函数名称 进行查阅

  • 7
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Fortran和C语言的混编是通过将Fortran代码编译成目标文件(.o文件),然后在C语言程序中调用这些目标文件来实现的。在混编过程中,需要注意以下几点: 1. Fortran和C语言的语法不同,但是它们最终都会被编译成汇编语言,因此可以在C语言程序中调用Fortran函数。这是因为编译生成的目标文件都使用汇编语言进行通信\[1\]。 2. 在C++程序中调用Fortran函数时,可以使用extern "C"关键字来指定使用C语言的函数命名规则。具体的做法是在C++代码中使用extern "C"来包裹Fortran函数的声明\[2\]。 3. 在混编过程中,需要注意函数名的差异。Fortran中的函数名为sub_fortran,而在C语言中,编译生成的函数名为sub_fortran_。这是因为Fortran编译文件之后会在函数名后面默认加上下划线,所以在C语言调用时也需要加上下划线。反过来,如果是Fortran想要调用C语言中的函数,需要在函数名前面加上下划线\[3\]。 综上所述,Fortran和C语言的混编可以通过将Fortran代码编译成目标文件,并在C语言程序中调用这些目标文件来实现。在混编过程中,需要注意语法差异以及函数名的对应关系。 #### 引用[.reference_title] - *1* *2* *3* [Linux下C++和Fortran的混编](https://blog.csdn.net/qq_40583925/article/details/123024724)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉开水白菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值