Linux中一切都是文件。
学习使用man指令查询函数功能。
fopen()函数
函数原型:FILE *fopen(const char *pathname, const char *mode);
pathname表示要打开的文件;mode指定打开文件的模式。
例如:FILE * fp = fopen("1.txt","w");
FILE *fp :定义了一个指向 FILE 类型的指针 fp 。FILE 是 C 语言中用于表示文件的数据结构。
fopen("1.txt", "w") :这是一个函数调用,用于打开文件。
"w"是文件打开模式。
"1.txt" :是要打开文件的文件名。
文件打开模式:
- "w" :以写入模式打开文件,如果文件不存在,则创建一个新文件;如果文件已存在,则清空文件内容。
- "r" :以只读模式打开文件。如果文件不存在,则打开失败。
例如:FILE *fp = fopen("data.txt", "r"); 用于只读方式打开 data.txt 文件。 - "a" :以追加模式打开文件。如果文件不存在,则创建一个新文件。写入的数据会添加到文件末尾。
比如:FILE *fp = fopen("log.txt", "a"); 可用于向日志文件追加新的记录。 - "r+" :以读写模式打开文件。文件必须存在。
例如:FILE *fp = fopen("file.txt", "r+"); 允许对文件进行读取和写入操作。 - "w+" :以读写模式打开文件。如果文件不存在,则创建新文件;如果文件存在,则清空文件内容。
比如:FILE *fp = fopen("output.txt", "w+"); 常用于创建新文件或覆盖旧文件并进行读写操作。 - "a+" :以读写模式打开文件。如果文件不存在,则创建新文件;读取操作从文件开头开始,写入操作则添加到文件末尾。
例如:FILE *fp = fopen("data_store.txt", "a+"); 适用于既需要读取文件已有内容,又要在末尾添加新数据的情况
#include <stdio.h> // 包含标准输入输出头文件
int main(int argc, char *argv[])
{
FILE * fp = fopen("1.txt","w"); // 以只写模式打开文件"1.txt",获取文件指针
if(NULL == fp) // 如果文件打开失败,文件指针为 NULL
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
return 0; // 程序正常结束,返回 0
}
fputc(写入) / fgetc(读取)
fputc()
是 C 标准库中的一个函数,用于向文件中写入一个字符。
它的函数原型为:int fputc(int c, FILE *stream)
c
:要写入的字符。stream
:指向要写入的文件的FILE
指针。
函数返回写入的字符,如果发生错误则返回 EOF
(通常被定义为 -1
)。
如果要依次写入字符 '1'
到 '9'
:
FILE *fp = fopen("1.txt", "w");
if (fp!= NULL)
{
for (int i = '1'; i <= '9'; i++)
{
fputc(i, fp);
}
fclose(fp);
}
#include <stdio.h> // 包含标准输入输出头文件
int main(int argc, char *argv[])
{
FILE * fp = fopen("1.txt","w"); // 以只写模式打开文件"1.txt",获取文件指针
if(NULL == fp) // 如果文件打开失败,文件指针为 NULL
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
int ret = fputc('h',fp); // 向文件中写入字符 'h',并获取返回值
if(-1 == ret) // 如果返回值为 -1,表示写入失败
{
printf("fputc error\n"); // 打印"fputc error"
return 1; // 程序异常结束,返回 1
}
fputc('e',fp); // 向文件中写入字符 'e'
fputc('l',fp); // 向文件中写入字符 'l'
fputc('l',fp); // 向文件中写入字符 'l'
fputc('o',fp); // 向文件中写入字符 'o'
fclose(fp); // 关闭文件
return 0; // 程序正常结束,返回 0
}
fgetc()
是 C 标准库中的一个函数,用于从指定的文件流中读取一个字符。
它的函数原型为:int fgetc(FILE *stream)
stream
:指向要读取的文件流的FILE
指针。
函数返回读取到的字符,如果到达文件末尾或发生错误,则返回 EOF
(通常被定义为 -1
)。
#include <stdio.h> // 包含标准输入输出头文件
int main(int argc, char *argv[])
{
FILE * fp = fopen("1.txt","r"); // 以只读模式打开文件"1.txt",获取文件指针
if(NULL == fp) // 如果文件打开失败,文件指针为 NULL
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
while(1) // 进入一个无限循环
{
int c = fgetc(fp); // 从文件中读取一个字符,并将其值赋给 c
if(EOF == c) // 如果读取到文件末尾(EOF)
{
break; // 退出循环
}
printf("%c\n",c); // 打印读取到的字符
}
fclose(fp); // 关闭文件
return 0; // 程序正常结束,返回 0
}
从命令行指定的源文件中读取字符,并将其逐个写入到指定的目标文件中:
#include <stdio.h> // 包含标准输入输出头文件
int main(int argc, char *argv[])
{
if(argc < 3) // 检查命令行参数的数量是否小于 3
{
printf("usage:./a.out srcfile dstfile\n"); // 打印使用说明
return 1; // 程序异常结束,返回 1
}
FILE *src = fopen(argv[1], "r"); // 以只读模式打开命令行参数中的第一个文件,并获取文件指针
FILE *dst = fopen(argv[2], "w"); // 以只写模式打开命令行参数中的第二个文件,并获取文件指针
if(NULL == src || NULL == dst) // 如果源文件或目标文件打开失败
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
while(1) // 进入一个无限循环
{
int c = fgetc(src); // 从源文件中读取一个字符,并将其值赋给 c
if(EOF == c) // 如果读取到源文件末尾(EOF)
{
break; // 退出循环
}
fputc(c, dst); // 将读取到的字符写入到目标文件中
}
fclose(dst); // 关闭目标文件
fclose(src); // 关闭源文件
return 0; // 程序正常结束,返回 0
}
fputs / fgets
fputs()
是 C 标准库中的一个函数,用于将一个字符串写入到指定的文件流中。
它的函数原型为:int fputs(const char *str, FILE *stream)
str
:要写入的字符串。stream
:指向目标文件的FILE
指针。
函数返回一个非负值表示成功写入,否则返回 EOF
表示发生错误。
fputs()
常用于将一段文本内容一次性写入文件。
#include <stdio.h> // 包含标准输入输出头文件
int main(int argc, char *argv[])
{
FILE * fp = fopen("1.txt","w"); // 以只写模式打开文件"1.txt",获取文件指针
if(NULL == fp) // 如果文件打开失败,文件指针为 NULL
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
char data[]="hello,world"; // 定义要写入文件的字符串
int ret = fputs(data,fp); // 将字符串写入文件,并获取返回值
if(EOF == ret) // 如果返回值为 EOF,表示写入失败
{
printf("fputs error\n"); // 打印"fputs error"
return 1; // 程序异常结束,返回 1
}
fclose(fp); // 关闭文件
return 0; // 程序正常结束,返回 0
}
fgets()
是 C 标准库中的一个函数,用于从指定的文件流中读取一行字符串。
它的函数原型为:char *fgets(char *str, int n, FILE *stream)
str
:用于存储读取到的字符串的字符数组。
n
:指定读取的最大字符数(包括字符串结束符'\0'
)。stream
:指向要读取的文件流的FILE
指针。
函数返回值:
- 成功读取到一行字符串时,返回
str
。 - 到达文件末尾或发生错误时,返回
NULL
。
#include <stdio.h> // 包含标准输入输出头文件
int main(int argc, char *argv[])
{
FILE * fp = fopen("/etc/passwd","r"); // 以只读模式打开 "/etc/passwd" 文件,并获取文件指针
if(NULL == fp) // 如果文件打开失败,文件指针为 NULL
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
char buf[1024]={0}; // 定义一个 1024 字节的字符数组,并初始化为 0 (1k - 4k 通常是常见的缓冲区大小范围)
while(1) // 进入一个无限循环
{
char* s = fgets(buf, sizeof(buf), fp); // 从文件中读取一行到 buf 中,并获取返回值
if(NULL == s) // 如果返回值为 NULL,表示已到达文件末尾或发生错误
{
break; // 退出循环
}
printf("%s\n", buf); // 打印读取到的这一行
}
fclose(fp); // 关闭文件
return 0; // 程序正常结束,返回 0
}
#include <stdio.h> // 包含标准输入输出头文件
int main(int argc, char *argv[])
{
FILE * fp = fopen("/etc/passwd","r"); // 以只读模式打开 "/etc/passwd" 文件,并获取文件指针
if(NULL == fp) // 如果文件打开失败,文件指针为 NULL
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
char buf[1024]={0}; // 定义一个 1024 字节大小的字符数组 buf,并初始化为 0
while(1) // 进入一个无限循环
{
char* s = fgets(buf, sizeof(buf), fp); // 从文件中读取一行内容到 buf 中,并获取返回值
if(NULL == s) // 如果返回值为 NULL,表示已到达文件末尾或发生错误
{
break; // 退出循环
}
printf("%s\n", buf); // 打印读取到的这一行内容
}
fclose(fp); // 关闭文件
return 0; // 程序正常结束,返回 0
}
这段代码的主要作用是打开指定的文件(/etc/passwd
),逐行读取文件内容并将其打印出来,直到读取到文件末尾为止。
fwrite / fread
fwrite 函数的原型为 size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 。
它的参数包括要写入的数据的指针 ptr 、每个元素的大小 size 、元素的个数 nmemb 和文件指针 stream 。如果成功,该函数返回实际写入的元素总数,这个总数是一个 size_t 类型的整型数据。如果返回值与 nmemb 参数不同,则可能表示出现了错误。
实现将一个结构体 PER
的实例数据写入到一个文件中。
#include <stdio.h> // 包含标准输入输出头文件
#include <string.h> // 包含字符串操作头文件
// 定义一个名为 PER 的结构体
typedef struct
{
char name[50]; // 用于存储名字的字符数组
int age; // 用于存储年龄的整数
char phone[15]; // 用于存储电话号码的字符数组
}PER;
// 主函数
int main(int argc, char *argv[])
{
FILE * fp = fopen("1.txt","w"); // 以写入模式打开文件"1.txt",并获取文件指针
if(NULL == fp) // 如果文件打开失败,文件指针为 NULL
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 返回 1 表示程序异常结束
}
PER per; // 定义 PER 类型的结构体变量 per
strcpy(per.name, "zhangsan"); // 将字符串"zhangsan"复制到 per 的 name 成员
per.age = 20; // 为 per 的 age 成员赋值 20
strcpy(per.phone, "111222333"); // 将字符串"111222333"复制到 per 的 phone 成员
size_t ret = fwrite(&per, sizeof(per), 1, fp); // 将 per 的内容写入文件
// 如果实际写入的个数不等于期望写入的个数 1
if(ret!= 1)
{
printf("fwrite error\n"); // 打印"fwrite error"
return 1; // 返回 1 表示程序异常结束
}
fclose(fp); // 关闭文件
return 0; // 返回 0 表示程序正常结束
}
fread函数的原型为 size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 。
它的第一个参数 ptr 是指向接收数据的内存地址,第二个参数 size 是每个元素的大小,第三个参数 nmemb 是要读取的元素个数,第四个参数 stream 是文件指针。
#include <stdio.h> // 包含标准输入输出头文件
#include <string.h> // 包含字符串处理头文件
// 定义一个名为 PER 的结构体
typedef struct
{
char name[50]; // 存储名字的字符数组
int age; // 存储年龄的整数
char phone[15]; // 存储电话号码的字符数组
}PER;
// 主函数
int main(int argc, char *argv[])
{
FILE * fp = fopen("1.txt","r"); // 以只读模式打开文件"1.txt",获取文件指针
if(NULL == fp) // 如果文件打开失败,文件指针为 NULL
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
PER per;
// memset(&per,0,sizeof(per)); // 注释掉的这行,可用于将 per 所占据的内存初始化为 0
bzero(&per,sizeof(per)); // 将 per 所占据的内存初始化为 0
size_t ret = fread(&per,sizeof(per),1,fp); // 从文件中读取一个结构体大小的数据到 per 中
printf("name:%s age:%d phone:%s\n",per.name,per.age,per.phone); // 打印读取到的结构体成员值
if(ret!= 1) // 如果实际读取的个数不等于期望读取的个数 1
{
printf("fread error\n"); // 打印"fread error"
return 1; // 程序异常结束,返回 1
}
fclose(fp); // 关闭文件
return 0; // 程序正常结束,返回 0
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
char name[50];
int age;
char phone[15];
}PER;
int main(int argc, char *argv[])
{
FILE * src_fp = fopen("/home/linux/1.png","r"); // 以只读模式打开源图片文件,并获取文件指针
FILE* dst_fp = fopen("2.png","w"); // 以只写模式创建目标图片文件,并获取文件指针
if(NULL == src_fp || NULL == dst_fp) // 如果源文件或目标文件打开失败
{
printf("fopen error\n"); // 打印"fopen error"
return 1; // 程序异常结束,返回 1
}
int size = 160743; // 定义要读取和写入的字节数
char *p = (char* )malloc(size); // 动态分配内存用于存储读取的文件内容
fread(p, size, 1, src_fp); // 从源文件读取指定字节数的数据到分配的内存中
fwrite(p, size, 1, dst_fp); // 将读取的数据写入到目标文件中
fclose(dst_fp); // 关闭目标文件
fclose(src_fp); // 关闭源文件
free(p); // 释放动态分配的内存
return 0;
}
这段代码的主要功能是将一个图片文件(/home/linux/1.png
)的内容读取到动态分配的内存中,然后将其写入到另一个图片文件(2.png
)中。需要注意的是,在实际应用中,对于图片等二进制文件的处理,要确保文件操作的完整性和正确性,并且要注意内存的合理分配和释放,以避免内存泄漏等问题。