C/C++写文件的几种方法与注意事项

C语言读写文件

在C语言中,你可以使用标准库中的文件操作函数来向文件中写入字符文本。以下是一些常用的函数和步骤:

  • 打开文件:使用 fopen 函数打开一个文件,如果文件不存在,则创建它。
  • 写入文件:使用 fprintf、fputs 或 fwrite 等函数将数据写入文件。
  • 关闭文件:使用 fclose 函数关闭文件。
  1. 下面是一个简单的例子,演示如何使用这些函数将字符串写入文件
#include <stdio.h>
int main() {
    FILE *file; // 文件指针
    const char *text = "Hello, World!\n"; // 要写入的文本
    // 打开文件,"w" 表示写入模式,如果文件已存在,则截断为零长度,即清空文件
    file = fopen("example.txt", "w");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    // 写入文本
    fputs(text, file);
    // 关闭文件
    fclose(file);
    return 0;
}
  1. 在C语言中,读取文件内容可以通过多种方式实现,这里介绍几种常用的方法:

    1. 使用 fgetc 或 getc 函数
      这两个函数用于从文件中读取单个字符。fgetc 需要一个文件指针作为参数,而 getc 是 fgetc 的宏定义,可以直接使用文件指针。
#include <stdio.h>
int main() {
    FILE *file;
    char ch;
    // 打开文件,"r" 表示只读模式
    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    // 读取字符直到文件结束
    while ((ch = fgetc(file)) != EOF) {
        putchar(ch); // 输出读取的字符
    }
    // 关闭文件
    fclose(file);
    return 0;
}

使用 fgets 函数
fgets 函数用于从文件中读取一行字符串,直到遇到换行符或文件结束。

#include <stdio.h>
int main() {
    FILE *file;
    char buffer[256]; // 存储读取的行
    // 打开文件,"r" 表示只读模式
    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    // 读取行直到文件结束
    while (fgets(buffer, sizeof(buffer), file) != NULL) {
        printf("%s", buffer); // 输出读取的行
    }
    // 关闭文件
    fclose(file);
    return 0;
}
使用 fread 函数

fread 函数用于从文件中读取一个数据块。它需要指定要读取的元素数量和元素大小。

#include <stdio.h>

int main() {
    FILE *file;
    char buffer[256]; // 存储读取的数据块
    // 打开文件,"r" 表示只读模式
    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    // 读取数据块
    size_t bytesRead = fread(buffer, sizeof(char), sizeof(buffer), file);
    if (bytesRead > 0) {
        printf("%s", buffer); // 输出读取的数据块
    }
    // 关闭文件
    fclose(file);
    return 0;
}

在使用这些函数时,记得检查文件是否成功打开,并在读取操作完成后关闭文件。这些函数都会返回一个值,表示操作的结果,例如 fgetc 返回读取的字符(如果到达文件末尾则返回 EOF),fgets 返回指向缓冲区的指针(如果到达文件末尾或发生错误则返回 NULL),fread 返回实际读取的元素数量。

fgetc什么意思?

fgetc 是 C 语言标准库中的一个函数,用于从文件流中读取下一个字符。这个函数是 stdio.h 头文件中定义的,其全称是 "file get character",即“从文件中获取字符”。

函数原型如下:

cint fgetc(FILE *stream);

  • 参数:stream 是指向 FILE 对象的指针,这个 FILE 对象标识了要从中读取字符的文件流。
  • 返回值:成功时,fgetc 返回读取的字符(一个 int 类型的值,可以是任何字符,包括 '\0')。如果到达文件末尾(EOF),则返回 EOF。在发生读取错误时,fgetc 也返回 EOF,可以通过 ferror 函数检查是否发生了错误。
    fgetc 函数每次调用只会从文件流中读取一个字符,包括空字符('\0')和换行符('\n')。这个函数常用于逐个字符地读取文件内容,尤其是在需要对文件中的每个字符进行处理时。

下面是一个使用 fgetc 读取文件内容的简单示例:

#include <stdio.h>
int main() {
    FILE *file;
    int ch;
    // 打开文件
    file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    // 逐个字符读取文件内容
    while ((ch = fgetc(file)) != EOF) {
        putchar(ch); // 将读取的字符输出到标准输出
    }
    // 关闭文件
    fclose(file);
    return 0;
}

fputs写入文件和fwrite写入文件有什么区别?

fputs 和 fwrite 是 C 语言标准库中用于写入文件的两个不同函数,它们的主要区别在于它们处理数据的方式和用途。以下是它们的主要区别:

  • fputs 函数

    • 用途:fputs 用于将一个字符串写入文件。
    • 函数原型:int fputs(const char *s, FILE *stream);
    • 参数:
      • s:指向要写入的字符串的指针。
      • stream:指向 FILE 对象的指针,该对象标识了要写入的文件流。
    • 返回值:成功时返回 0,失败时返回 EOF。
    • 特点:
      1. 只能写入字符串(字符数组),不能写入其他类型的数据。
      2. 自动在字符串末尾添加空字符('\0'),因此不需要手动添加。
    • 常用于写入文本文件。
  • fwrite 函数

    • 用途:fwrite 用于将任意类型的数据写入文件。
    • 函数原型:size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
    • 参数:
      • ptr:指向要写入的数据的指针。
      • size:每个元素的大小(以字节为单位)。
      • nmemb:要写入的元素数量。
      • stream:指向 FILE 对象的指针,该对象标识了要写入的文件流。
    • 返回值:成功时返回写入的元素数量,失败时返回 0。
    • 特点:
      1. 可以写入任意类型的数据,包括结构体、数组等。
      2. 不会自动添加空字符,需要手动处理。
        常用于写入二进制文件,也可以用于写入文本文件,但需要手动处理字符串的空字符。

总结

  1. 文本文件:如果你只需要写入字符串,fputs 是一个简单且方便的选择,因为它自动处理空字符。
  2. 二进制文件:如果你需要写入非字符串类型的数据,或者需要更精细地控制数据的写入,fwrite 是更好的选择,因为它可以处理任意类型的数据。
    下面是一个使用 fputs 和 fwrite 写入文件的示例
#include <stdio.h>
#include <string.h>

int main() {
    FILE *file;
    char text[] = "Hello, World!\n";
    int data[] = {1, 2, 3, 4, 5};

    // 使用 fputs 写入文本
    file = fopen("text_file.txt", "w");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    fputs(text, file);
    fclose(file);
    // 使用 fwrite 写入二进制数据
    file = fopen("binary_file.bin", "wb");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    fwrite(data, sizeof(int), sizeof(data) / sizeof(int), file);
    fclose(file);
    return 0;
}

在这个示例中,fputs 用于写入文本文件,而 fwrite 用于写入二进制文件。

fopen("binary_file.bin", "wb"); “wb”中的b有什么作用

在C语言中,fopen 函数用于打开文件,其第二个参数是模式字符串,用于指定文件的打开模式。在模式字符串中加入 b(字母“b”)是为了指定文件以二进制模式打开。具体来说:

  • "w":打开一个空文件用于写入,如果文件已存在,则截断为零长度,即清空文件。
  • "wb":以二进制模式打开一个空文件用于写入,如果文件已存在,则截断为零长度。
  • b 的作用主要体现在不同操作系统对文件的处理上。在某些操作系统(特别是较旧的操作系统)中,文本模式和二进制模式的文件处理有所不同:

文本模式:在文本模式下,操作系统可能会对换行符进行转换(例如,在Windows中,\n 会被转换为 \r\n),并且可能会执行其他一些特定的文本处理。
二进制模式:在二进制模式下,操作系统不会对文件内容进行任何转换,文件内容会被原样读写。这对于非文本文件(如图片、音频、视频等)非常重要,因为这些文件包含二进制数据,任何转换都可能导致数据损坏。
在现代操作系统中,文本模式和二进制模式的区别可能不那么明显,但为了确保跨平台兼容性和数据的完整性,特别是在处理二进制文件时,使用 "wb"(写入二进制)或 "rb"(读取二进制)模式是一个好习惯。

下面是一个使用 "wb" 模式打开文件并写入数据的示例

#include <stdio.h>

int main() {
    FILE *file;
    int data[] = {1, 2, 3, 4, 5};
    // 以二进制模式打开文件用于写入
    file = fopen("binary_file.bin", "wb");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    // 写入二进制数据
    fwrite(data, sizeof(int), sizeof(data) / sizeof(int), file);
    // 关闭文件
    fclose(file);
    return 0;
}

在这个示例中,fopen 使用 "wb" 模式打开文件,确保数据以二进制形式写入,不受任何文本转换的影响。

如果我使用的是“w”,有区别吗?

如果你使用的是 "w" 而不是 "wb" 来打开文件,那么在大多数现代操作系统中,实际上并没有太大的区别,尤其是在处理文本文件时。"w" 模式默认就是用来写入文本文件的,而 "wb" 主要用于强调文件将以二进制模式打开。

以下是一些细微的区别和考虑因素:

  1. 文本文件 vs 二进制文件

    • 使用 "w" 打开文件时,你通常处理的是文本文件,这意味着文件内容是由字符和字符串组成,可能会受到换行符转换等文本模式特有的处理。
    • 使用 "wb" 打开文件时,你处理的是二进制文件,这意味着文件内容可能包含任何类型的数据(包括文本、图像、音频等),不会受到文本模式的处理。
  2. 跨平台兼容性

    • 在不同的操作系统中,文本模式和二进制模式的处理可能有所不同。例如,在Windows系统中,文本模式下会将 \n 转换为 \r\n,而在Linux和macOS中,文本模式下 \n 保持不变。使用 "wb" 可以确保你的程序在不同平台上以相同的方式处理文件,特别是在处理二进制数据时。
  3. 性能

    • 对于文本文件,使用 "w""wb" 在性能上通常没有显著差异。但是,如果你在处理大量的数据或者需要频繁地打开和关闭文件,使用 "wb" 可以减少由于文本模式处理带来的额外开销。
  4. 代码清晰性

    • 使用 "wb" 可以明确地表明你的意图是处理二进制数据,这有助于代码的可读性和维护性。特别是当其他开发者阅读你的代码时,使用 "wb" 可以立即告诉他们这个文件是以二进制模式打开的。

总结来说,如果你确信你正在处理的是纯文本文件,并且你的程序只在一种操作系统上运行,那么使用 "w" 就足够了。但是,如果你需要处理二进制数据,或者你的程序需要在不同的操作系统上运行,使用 "wb" 是一个更安全、更清晰的做法。
我使用fwrite("w")写入文本数据,如果我使用getc来获取这个数据,会乱码吗
如果你使用 fwrite 以二进制模式(例如 "wb")写入文本数据,然后使用 getcfgetc 来读取这些数据,通常不会出现乱码。这是因为 fwritegetc/fgetc 都是以二进制方式处理数据的,它们不会对数据内容进行任何转换。

下面是详细说明:

  1. 写入数据

    • 当你使用 fwrite 以二进制模式("wb")写入文本数据时,数据会被原样写入文件,包括所有的字符和空字符('\0')。
  2. 读取数据

    • 当你使用 getcfgetc 读取这些数据时,它们会逐个字符地从文件中读取,包括所有的字符和空字符('\0')。由于这些函数以二进制方式读取数据,它们不会对数据内容进行任何转换,因此读取的数据将与写入的数据完全一致。
  3. 乱码问题

    • 只要你在写入和读取数据时使用相同的模式(二进制模式),并且确保读取的数据量与写入的数据量相匹配,就不会出现问题。乱码通常发生在不同的编码或模式之间,例如将文本模式下的数据与二进制模式下的数据混合使用。

下面是一个示例,演示使用 fwrite 写入文本数据,然后使用 getc/fgetc 读取数据:

#include <stdio.h>

int main() {
    FILE *file;
    const char *text = "Hello, World!\n";
    char ch;
    // 使用 fwrite 以二进制模式写入文本数据
    file = fopen("example.bin", "wb");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    fwrite(text, sizeof(char), strlen(text) + 1, file); // 包括空字符
    fclose(file);
    // 使用 getc 读取数据
    file = fopen("example.bin", "rb");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    while ((ch = getc(file)) != EOF) {
        putchar(ch); // 输出读取的字符
    }
    fclose(file);
    return 0;
}

在这个示例中,程序使用 fwrite 以二进制模式写入文本数据,然后使用 getc 读取数据。由于写入和读取都以二进制模式进行,因此读取的数据将与写入的数据完全一致,不会出现乱码。

总之,只要你在写入和读取数据时使用相同的模式(二进制模式),并且确保读取的数据量与写入的数据量相匹配,就不会出现乱码问题。

hexdump怎么用(可以用于查看文件二进制数据)

hexdump 是一个在 Linux 和其他 Unix-like 系统中常用的命令行工具,用于以十六进制格式显示文件内容,也可以显示相应的 ASCII 字符。以下是 hexdump 的一些基本用法和选项:

  1. 基本用法

    • hexdump [文件]:显示整个文件的十六进制表示。
    • hexdump -C [文件]:以十六进制和 ASCII 字符的混合格式显示数据,每行显示 16 个字节,并显示字节的偏移量。
  2. 选项

    • -b:每个字节显示为8进制。
    • -c:每个字节显示为ASCII字符。
    • -d:两个字节显示为10进制。
    • -o:两个字节显示为8进制。
    • -x:双字节十六进制显示。
    • -n length:只格式化输入文件的前 length 个字节。
    • -s offset:从偏移量 offset 开始输出。
    • -v:显示每个字节的完整值,而不是仅显示可打印字符。
    • -e:指定格式字符串,格式字符串包含在一对单引号中,格式字符串形如:'a/b "format1" "format2"',其中 ab 分别表示对每 a 个和 b 个输入字节应用 format1format2 格式。
  3. 高级用法

    • -e 选项允许你指定自定义的格式字符串,例如:hexdump -e '16/1 "%02x" "%_p"' [文件],这里 16/1 表示每16个字节应用一次格式,%02x 表示两位十六进制数,%_p 表示打印字节的位置。
  4. 示例

    • 查看文件的前 16 个字节:hexdump -n 16 [文件]
    • 从文件的第 16 个字节开始显示内容:hexdump -s 16 [文件]

hexdump 命令非常有用,特别是在分析二进制文件、网络数据包或调试程序时。通过不同的选项和参数,你可以灵活地查看和分析文件内容。

hexdump打印信息的开头的第一列是什么含义
在使用 hexdump 命令时,打印信息的开头的第一列通常表示字节的偏移量(Offset),它指示了每行显示的十六进制数据在文件中的起始位置。这个偏移量通常以十六进制数的形式显示,并且每行的偏移量都会递增,以反映文件中数据的连续位置。

例如,如果你使用 hexdump -C file.txt 命令,你会看到输出的第一列是偏移量,如下所示:

00000000  48 65 6c 6c 6f 20 77  6f 72 6c 64 21 0a          |Hello world!.|
00000010  00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |...............|

在这个例子中:

  • 00000000 是第一行数据的偏移量,表示从文件的开头(位置0)开始。
  • 00000010 是第二行数据的偏移量,表示从文件的第16个字节开始。

偏移量的存在使得你可以轻松地定位文件中的特定位置,并且它们通常用于调试和分析文件结构。每行的偏移量后面跟着的是该行中每个字节的十六进制表示,以及可选的ASCII字符表示(如果你使用了 -C 选项)。

为什么我使用fwrite()写入char类型数据时,可以打开文件直接阅读。但如果我写入的是int类型数组,就不能直接打开文件阅读了?

当你使用 fwrite() 写入 char 类型数据时,你实际上是在写入文本数据,这些数据在文件中是以字符的形式存储的。每个 char 值对应一个字符,这些字符可以直接在文本编辑器中显示,因为文本编辑器就是用来显示字符的。

然而,当你使用 fwrite() 写入 int 类型数组时,情况就不同了。int 类型数据是二进制格式存储的,它们在内存中的表示方式与字符的ASCII码不同。当你在文本编辑器中打开一个包含二进制数据的文件时,编辑器会尝试将这些二进制数据解释为字符,这通常会导致乱码,因为这些数据并不是以字符编码的。

这里有几个关键点需要注意:

  1. 字符编码char 类型数据通常以字符编码(如ASCII或UTF-8)存储,这些编码设计用来表示可打印的字符。因此,当你写入 char 数据时,你实际上是在写入可以直接阅读的文本。

  2. 二进制数据int 类型数据是二进制格式的,它们在内存中的表示方式是为了计算机处理而设计的,而不是为了人类阅读。当你将这些数据写入文件时,你是在写入二进制数据,而不是文本。

  3. 字节顺序:不同的计算机架构可能有不同的字节顺序(大端或小端)。这意味着即使 int 值在内存中的表示方式在写入时是正确的,如果你在不同的架构上读取这些数据,可能会得到错误的值,因为字节的顺序可能被错误地解释。

  4. 数据解释:文本编辑器不知道如何解释二进制数据。它尝试将每个字节转换为对应的ASCII字符,如果字节值不在可打印字符的范围内,结果就是乱码。

如果你需要以文本形式查看 int 类型数组的内容,你需要将每个 int 值转换为字符表示(例如,使用 printf 或类似的方法将每个 int 格式化为字符串),然后再写入文件。这样,当你打开文件时,你看到的将是数值的文本表示,而不是二进制数据。

下面是一个示例,展示如何将 int 数组转换为字符串并写入文件:

#include <stdio.h>
#include <stdlib.h>
int main() {
    int data[] = {1, 2, 3, 4, 5};
    int n = sizeof(data) / sizeof(data[0]);
    FILE *file = fopen("data.txt", "w");
    for (int i = 0; i < n; i++) {
        fprintf(file, "%d\n", data[i]); // 将每个int转换为字符串并写入文件
    }
    fclose(file);
    return 0;
}

在这个示例中,每个 int 值都被转换为一个字符串,然后写入文件,这样你就可以在文本编辑器中直接阅读这些值了。

posted @   白柒  阅读(86)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
历史上的今天:
2024-01-24 assert用法
2024-01-24 C/C++ 常用输出流
点击右上角即可分享
微信分享提示