学习笔记2
@
目录课程:《Linux》
班级:2111
姓名:杨博川
学号:20211121
日期:2023年9月14日
一、学习笔记
1.C语言中的文件操作内容
在C语言中,文件操作是通过标准库中的文件操作函数来实现的。这些函数位于stdio.h
头文件中,提供了一组用于打开、读取、写入和关闭文件的函数。
下面是一些常用的文件操作函数:
-
FILE
类型:FILE
是一个结构体类型,用于表示一个文件。通常使用指向FILE
类型的指针来操作文件。 -
fopen
函数:用于打开文件,并返回一个指向FILE
类型的指针。它接受两个参数,第一个参数是文件名,第二个参数是打开模式(如读取、写入等)。FILE *fopen(const char *filename, const char *mode); ```
-
fclose
函数:用于关闭文件。它接受一个指向FILE
类型的指针作为参数,并返回一个整数值表示操作是否成功。int fclose(FILE *stream); ```
-
fread
函数:用于从文件中读取数据。它接受多个参数,包括一个指向数据缓冲区的指针、每个数据项的大小、要读取的数据项数以及一个指向要读取的文件的指针。size_t fread(void *ptr, size_t size, size_t count, FILE *stream); ```
-
fwrite
函数:用于将数据写入文件。它接受多个参数,包括一个指向数据的指针、每个数据项的大小、要写入的数据项数以及一个指向要写入的文件的指针。size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream); ```
-
fgetc
和fputc
函数:用于从文件中读取单个字符和写入单个字符。它们接受一个指向文件的指针作为参数,并返回读取或写入的字符。int fgetc(FILE *stream); int fputc(int character, FILE *stream); ```
-
fgets
和fputs
函数:用于从文件中读取字符串和写入字符串。它们接受多个参数,包括一个指向字符串的指针、要读取或写入的最大字符数以及一个指向文件的指针。char *fgets(char *str, int n, FILE *stream); int fputs(const char *str, FILE *stream); ```
这些函数只是C语言文件操作的一小部分。还有其他函数可以用于文件定位、错误处理等。在使用这些函数时,需要注意错误处理和文件指针的有效性,以确保正确操作文件。
2.文件操作都有什么?
文件操作在C语言中提供了一系列函数,用于打开、关闭、读取、写入和管理文件。下面是文件操作的一些常见功能:
-
打开文件:
fopen
:打开文件并返回一个指向文件的指针。
-
关闭文件:
fclose
:关闭先前打开的文件。
-
读取文件内容:
fgetc
:从文件中读取一个字符。fgets
:从文件中读取一行字符串。fread
:从文件中读取一定数量的数据。fscanf
:从文件中按格式读取数据。
-
写入文件内容:
fputc
:向文件中写入一个字符。fputs
:向文件中写入一行字符串。fwrite
:向文件中写入一定数量的数据。fprintf
:向文件中按格式写入数据。
-
文件定位:
fseek
:设置文件指针的位置。ftell
:获取文件指针的当前位置。rewind
:将文件指针重置到文件开头。
-
错误处理:
feof
:检查文件结束标志。ferror
:检查文件错误标志。perror
:输出与最近的文件操作相关的错误消息。
-
其他操作:
remove
:删除指定的文件。rename
:重命名文件。tmpfile
:创建一个临时文件。tmpnam
:生成一个唯一的临时文件名。
请注意,上述列出的函数只是C语言文件操作的一部分,还有其他函数和技术可用于更高级的文件操作,如目录操作、文件属性等。此外,还应该注意在进行文件操作时要进行错误检查,并适当处理可能出现的错误情况。
3.二进制文件和文本文件如何转换?
在C语言中,可以通过读取和写入文件的方式将二进制文件和文本文件进行相互转换。下面是一些常用的方法:
-
从二进制文件读取并写入文本文件:
- 打开二进制文件和文本文件,分别使用
fopen
函数打开文件并获取文件指针。 - 使用二进制读取函数(如
fread
)从二进制文件中读取数据。 - 使用文本写入函数(如
fprintf
、fputc
、fputs
等)将读取的数据写入文本文件中。 - 关闭二进制文件和文本文件,分别使用
fclose
函数关闭文件。
- 打开二进制文件和文本文件,分别使用
-
从文本文件读取并写入二进制文件:
- 打开文本文件和二进制文件,分别使用
fopen
函数打开文件并获取文件指针。 - 使用文本读取函数(如
fgets
、fscanf
等)从文本文件中读取数据。 - 使用二进制写入函数(如
fwrite
、fputc
等)将读取的数据写入二进制文件中。 - 关闭文本文件和二进制文件,分别使用
fclose
函数关闭文件。
- 打开文本文件和二进制文件,分别使用
需要注意的是,在进行文件转换时,需要根据文件的内容和格式来选择适当的读取和写入函数。对于文本文件,使用文本读写函数可以保留文本的可读性。而对于二进制文件,使用二进制读写函数可以确保数据的准确性和完整性。
此外,转换过程中还需要注意文件的打开模式和编码方式,以确保正确地处理文件的内容。
4.数据结构如何读写?
在C语言中,可以使用文件操作函数来读取和写入数据结构。读写数据结构的基本思路是将数据结构的内容以适当的格式写入文件,然后再从文件中读取相应的数据并填充到数据结构中。
下面是一种常见的方法来读写数据结构:
-
写入数据结构:
- 打开文件,使用
fopen
函数打开文件并获取文件指针。 - 将数据结构的内容格式化为字符串或二进制数据。
- 使用文件写入函数(如
fprintf
、fwrite
等)将格式化的数据写入文件中。 - 关闭文件,使用
fclose
函数关闭文件。
- 打开文件,使用
-
读取数据结构:
- 打开文件,使用
fopen
函数打开文件并获取文件指针。 - 使用文件读取函数(如
fscanf
、fread
等)从文件中读取数据。 - 将读取的数据按照相应的格式填充到数据结构中。
- 关闭文件,使用
fclose
函数关闭文件。
- 打开文件,使用
需要注意的是,在读写数据结构之前,要确保数据结构的成员变量的顺序和类型与文件中的数据一致。此外,还需注意数据结构的大小和对齐方式,以避免数据解析错误或内存访问问题。
另外,如果数据结构包含指针或引用其他数据结构,需要特别处理。在写入时,需要将指针或引用的数据写入到文件中,并在读取时重新构建指针或引用的关系。
总之,读写数据结构需要考虑数据的格式化、文件的打开模式、数据的填充和解析等因素,以确保数据的正确读写和一致性。
5.二进制文件操作
在C语言中,可以使用二进制文件操作函数对二进制文件进行读写。二进制文件操作主要针对文件中的原始二进制数据,不会进行字符编码或格式化转换。
下面是一些常用的二进制文件操作函数:
-
打开二进制文件:
- 使用
fopen
函数以二进制模式打开文件,模式参数为"rb"(读取)或"wb"(写入)。 - 例如:
FILE *file = fopen("filename", "rb");
- 使用
-
关闭二进制文件:
- 使用
fclose
函数关闭二进制文件。 - 例如:
fclose(file);
- 使用
-
读取二进制数据:
- 使用
fread
函数从二进制文件中读取数据。 fread
函数的参数包括要读取的数据缓冲区、每个数据项的大小、要读取的数据项数以及文件指针。- 例如:
fread(buffer, sizeof(type), count, file);
- 使用
-
写入二进制数据:
- 使用
fwrite
函数将二进制数据写入文件。 fwrite
函数的参数包括要写入的数据缓冲区、每个数据项的大小、要写入的数据项数以及文件指针。- 例如:
fwrite(buffer, sizeof(type), count, file);
- 使用
-
文件定位:
- 使用
fseek
函数设置文件指针的位置。 fseek
函数的参数包括文件指针、偏移量和起始位置。- 例如:
fseek(file, offset, SEEK_SET);
(从文件开头偏移offset字节)
- 使用
-
获取文件大小:
- 使用
fseek
和ftell
函数结合,可以获取二进制文件的大小。 - 首先使用
fseek
将文件指针移到文件末尾,然后使用ftell
获取文件指针的当前位置(即文件大小)。 - 例如:
fseek(file, 0, SEEK_END); // 移动到文件末尾 long size = ftell(file); // 获取文件大小
- 使用
上述函数是进行基本的二进制文件操作的关键函数。在实际使用时,需要根据具体需求和数据结构来读写文件,并进行适当的错误处理和数据验证。
6.相比于曾经我们关注文本文件的操作,我们以后该如何更多的关注操作二进制文件
操作二进制文件相比文本文件需要更多的关注数据的底层表示和处理,因为二进制文件中的数据以原始的二进制形式存储,没有经过字符编码或格式化转换。以下是一些建议,以更多地关注二进制文件的操作:
-
数据类型和结构:了解二进制数据的类型和结构对于正确地读取和解析文件至关重要。确保正确地定义和使用适当的数据类型和结构来表示文件中的数据。
-
字节序(Endianness):在处理跨平台的二进制文件时,需要考虑字节序问题。了解系统的字节序(大端序或小端序),并根据需要进行字节序转换。
-
内存对齐:了解和管理数据的内存对齐是操作二进制文件时的重要考虑因素。在涉及结构体或自定义数据类型时,确保正确的内存对齐,以免出现数据读写的错误或性能问题。
-
位操作:二进制文件中的某些数据可能以位为单位进行存储,因此熟悉位操作是处理这些数据的关键。使用位运算操作符(如位与、位或、位移等)来读取、设置或清除特定的位。
-
文件定位和随机访问:二进制文件通常具有固定的结构,可以通过文件定位函数(如
fseek
)在文件中跳转到特定位置。利用这一点,可以实现对文件的随机访问,读取或修改特定位置的数据。 -
数据校验:由于二进制文件中的数据没有像文本文件那样的可见字符表示,因此数据的正确性和完整性变得更加重要。使用校验和、哈希函数或其他方法来验证读取或写入的数据是否一致和完整。
-
文件格式规范:对于特定的二进制文件格式,可能有相应的规范或标准。了解并遵循文件格式规范可以更好地理解和处理文件中的数据。
-
错误处理和异常情况:在操作二进制文件时,需要特别注意错误处理和异常情况的处理。例如,文件不存在、读写错误、数据解析错误等情况都需要进行适当的处理和错误提示。
总之,操作二进制文件需要更多的底层知识和细致的处理,以确保数据的正确性和完整性。深入了解二进制文件的特性和相关操作函数,同时进行适当的数据验证和错误处理,可以更好地处理二进制文件。
二、部分代码展示
1.fget
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "r");
if (file == NULL) {
printf("无法打开文件!\n");
return 1; // 返回错误代码
}
char buffer[100]; // 用于存储读取的行
if (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("读取的内容:%s", buffer);
} else {
printf("读取失败或到达文件末尾!\n");
}
fclose(file); // 关闭文件
return 0;
}
2.fprint
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "w");
if (file == NULL) {
printf("无法打开文件!\n");
return 1;
}
int num1 = 10;
double num2 = 3.14159;
const char* str = "Hello, World!";
// 将格式化的输出写入文件
int numChars = fprintf(file, "整数:%d\n浮点数:%f\n字符串:%s\n", num1, num2, str);
if (numChars >= 0) {
printf("成功写入 %d 个字符到文件\n", numChars);
} else {
printf("写入文件失败\n");
}
fclose(file);
return 0;
}
3.fputs
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "w");
if (file == NULL) {
printf("无法打开文件!\n");
return 1;
}
const char* str = "Hello, World!";
// 将字符串写入文件
int result = fputs(str, file);
if (result != EOF) {
printf("字符串写入文件成功\n");
} else {
printf("字符串写入文件失败\n");
}
fclose(file);
return 0;
}
4.fscanf
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "r");
if (file == NULL) {
printf("无法打开文件!\n");
return 1;
}
int num1, num2;
char str[100];
// 从文件中读取格式化输入
int numItems = fscanf(file, "%d %d %s", &num1, &num2, str);
if (numItems == 3) {
printf("成功读取:%d %d %s\n", num1, num2, str);
} else {
printf("读取失败\n");
}
fclose(file);
return 0;
}
5.fseek
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "r");
if (file == NULL) {
printf("无法打开文件!\n");
return 1;
}
// 将文件位置指针移动到文件开头
fseek(file, 0L, SEEK_SET);
// 读取文件的前 10 个字符
char buffer[11];
size_t numRead = fread(buffer, sizeof(char), 10, file);
buffer[numRead] = '\0'; // 将字符串结束符添加到末尾
printf("读取的内容:%s\n", buffer);
fclose(file);
return 0;
}
5.fseek
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "r");
if (file == NULL) {
printf("无法打开文件!\n");
return 1;
}
// 将文件位置指针移动到文件开头
fseek(file, 0L, SEEK_SET);
// 读取文件的前 10 个字符
char buffer[11];
size_t numRead = fread(buffer, sizeof(char), 10, file);
buffer[numRead] = '\0'; // 将字符串结束符添加到末尾
printf("读取的内容:%s\n", buffer);
fclose(file);
return 0;
}
6.ftell
#include <stdio.h>
int main() {
FILE* file = fopen("example.txt", "r");
if (file == NULL) {
printf("无法打开文件!\n");
return 1;
}
// 获取当前文件位置指针的偏移量
long int offset = ftell(file);
printf("当前偏移量:%ld\n", offset);
fclose(file);
return 0;
}
三、苏格拉底检验
问题一
I:我在学习”C语言中的文件操作内容“知识点,请你以苏格拉底的方式对我进行提问,一次一个问题.
A:当你在C语言中进行文件操作时,你是否了解如何打开文件?
I:fopen
A:很好!那你知道在C语言中,fopen
函数的作用是什么?
I:我不知道,你的理解呢?
A:fopen
函数在C语言中用于打开文件。它接受两个参数:文件名和打开模式。文件名是一个字符串,表示要打开的文件的路径和名称。打开模式指定了文件的打开方式,例如读取("r")、写入("w")或追加("a")。
fopen
函数返回一个指向FILE
类型结构的指针,该结构用于表示文件流。通过这个指针,你可以进行后续的文件读取或写入操作。如果打开文件失败,fopen
函数将返回一个空指针(NULL
)。
所以,fopen
函数的作用是打开一个文件,为后续的文件操作提供文件流的指针。
I:你觉得我掌握的如何?
A:从你的回答来看,你对fopen
函数的作用有了基本的了解。你知道它用于打开文件,并且可以通过返回的文件指针进行后续的文件操作。不过,还有一些细节和参数方面的内容需要进一步学习和理解。你可以继续深入学习文件操作的其他知识点,例如打开模式、文件指针的使用、错误处理等。这样你就能更加熟练地进行文件操作了。加油!如果你有任何关于文件操作的具体问题,我会很乐意帮助你。
问题二
I:我在学习”makefile“知识点,请你以苏格拉底的方式对我进行提问,一次一个问题
A:很高兴你对学习"Makefile"知识点感兴趣!我将以苏格拉底的方式提问,帮助你更好地理解这个主题。
1.你知道Makefile的作用是什么吗?
I:你的回答是什么
A:抱歉,我误解了你的问题。请允许我重新提问:
1 你希望了解Makefile的作用是什么?
I:我不知道,你的回答是什么
A:Makefile是一个文本文件,它包含了一系列规则和命令,用于自动化程序的编译和构建过程。它的主要作用是描述源代码文件之间的依赖关系,并定义了如何编译和链接这些文件以生成最终的可执行文件或库。通过Makefile,你可以定义编译选项、目标文件、源文件以及编译和链接的规则,以便于在开发过程中更加高效地进行代码的管理和构建。
接下来是下一个问题:
2. Makefile中的规则是由什么组成的?
I:目标,依赖
A:非常好!你答对了。Makefile中的规则通常由两个主要部分组成:
1.目标(Target):目标是要生成的文件或执行的操作的名称。它可以是可执行文件、库文件或其他生成的输出文件。
2.依赖(Dependencies):依赖是目标所依赖的文件或其他目标。它们是构建目标所需的先决条件。当依赖项发生变化时,目标需要重新构建。
Makefile的规则定义了目标与依赖之间的关系,并指定了构建目标所需的命令。下一个问题是:
3. 在Makefile中,如何使用规则来描述目标和依赖之间的关系?
I:依赖项列表
A:非常好!你答对了。在Makefile中,可以使用规则来描述目标和依赖之间的关系。这可以通过指定目标以及其所依赖的文件或其他目标来实现。依赖项以依赖项列表的形式出现在规则中。
例如,下面是一个简单的示例规则:
target: dependency1 dependency2
command1
command2
在这个例子中,target
是目标,dependency1
和dependency2
是目标所依赖的文件或其他目标。command1
和command2
是构建目标所需的命令。
通过这样的规则,Make工具可以根据目标和依赖之间的关系,判断哪些目标需要重新构建,以及执行构建所需的命令。
接下来是下一个问题:
- 在Makefile中,如何编写规则中的命令?
I:我不知道,你的回答是什么
A:非常抱歉,我之前的回答可能有些模糊。请允许我重新回答你的问题。
在Makefile中,可以使用规则来描述目标和依赖之间的关系,并编写规则中的命令。命令通常出现在规则的下一行,并以一个或多个Tab键开始。
以下是一个示例规则,展示了如何编写命令:
target: dependency1 dependency2
command1
command2
在这个例子中,target
是目标,dependency1
和dependency2
是目标所依赖的文件或其他目标。命令 command1
和 command2
是构建目标所需的实际命令。这些命令将在执行Makefile时按顺序执行。
需要注意的是,在编写Makefile规则时,命令行必须以Tab键开始,而不是空格。这是为了与其他空格缩进的内容进行区分。
希望这次解答更加清晰明了。如果你还有其他问题,请随时提问。
标签:文件,读取,二进制,写入,笔记,学习,file,函数 From: https://www.cnblogs.com/bochuan/p/17709916.html