C语言零基础入门教程:186-218节


186. 字符串

字符串是由一系列字符组成的文本。它可以通过字符数组或指针来表示。C 语言中的字符串通常以空字符 '\0' 结尾来标记字符串的结束。接下来,我们将介绍字符串的不同表示方式以及它们的使用方法。

1. 单个字符

C 语言中,单个字符可以通过字符类型(char)来表示。例如:

char c = 't';
printf("%c\n\n", c);  // 输出:t
  • 't' 是一个单个字符,使用 %c 来输出。
2. 字符串数组

可以使用字符数组来存储一个字符串。一个字符数组可以存储多个字符,并且最后会自动加入一个 '\0' 作为字符串的结束符。

char arr[] = { "Hello" };  // 包含 'H', 'e', 'l', 'l', 'o', '\0'
arr[0] = 'W';  // 可以修改字符数组的内容
printf("%s\n\n", arr);  // 输出:Wello
  • 这里,arr[] 实际上是一个字符数组,存储了 Hello 字符串。
  • 数组中的每个字符都被存储为 char 类型,最后自动加上 '\0' 来表示字符串的结束。
3. 字符串常量

字符串常量是不可修改的,因此使用指针来存储字符串时,不能修改字符串的内容。

char* ptr = "Hello";  // 使用指针指向字符串
printf("%c\n", *ptr);  // 输出:H
  • ptr 是一个指向字符串常量 "Hello" 的指针。*ptr 表示指向的字符,即 'H'
  • 如果尝试修改 ptr 指向的内容,如 ptr[0] = 'w';,将会报错,因为字符串常量是只读的。
4. 字符串的数组和指针

C 语言中的字符串可以用字符数组或字符指针来表示。它们在内存中是不同的:

  • 字符数组:存储字符和 '\0',并且可以被修改。
  • 字符指针:指向一个字符串常量,不能被修改。
char string[6] = "hello";  // 字符数组存储字符串 "hello" + '\0'
printf("%s\n\n", string);   // 输出:hello
  • string 是一个字符数组,它足够大来存储 "hello" 和结束符 '\0',所以它的长度是 6。
  • 如果尝试将字符数组的长度设置为 5,就会遇到问题,因为它没有空间存储 '\0' 结束符,可能会导致字符串截断或未定义行为。
5. 完整代码示例
#include <stdio.h>

int main(void) {

    // 单个字符
    char c = 't';
    printf("%c\n\n", c);  // 输出:t

    // 字符串作为字符数组
    char arr[] = { "Hello" };  // 包含 'H', 'e', 'l', 'l', 'o', '\0'
    arr[0] = 'W';  // 修改字符数组的内容
    printf("%s\n\n", arr);  // 输出:Wello

    // 字符串常量
    char string[6] = "hello";  // 存储字符串 "hello" 和 '\0'
    printf("%s\n\n", string);  // 输出:hello

    // 字符串指针
    char* ptr = "Hello";  // 字符指针指向字符串常量
    printf("%c\n", *ptr);  // 输出:H

    // ptr[0] = 'w';  // 错误!尝试修改字符串常量会报错

    return 0;
}
6. 输出结果
t

Wello

hello

H
7. 总结
  • 单个字符使用 char 类型表示,使用 %c 输出。
  • 字符串可以通过字符数组或字符指针表示,但字符数组可以修改内容,而字符指针指向的字符串常量则是只读的。
  • 字符数组必须包含足够的空间来存储字符串及其结束符 '\0'

187. strcpy_s 的用法

strcpy_s 是一种安全的字符串复制函数,通常用于防止 strcpy 中的缓冲区溢出问题。与传统的 strcpy 不同,strcpy_s 需要传入目标缓冲区的大小,它会在复制时进行边界检查,从而避免复制时超出目标数组的大小。

1. strcpy_s 函数原型:
errno_t strcpy_s(char *dest, rsize_t destsz, const char *src);
  • dest:目标字符串数组。
  • destsz:目标数组的大小(以字符为单位)。
  • src:源字符串。

如果 strcpy_s 发现目标数组不够大来存放源字符串,它会返回一个错误,并不会执行复制操作。

2. 代码示例
#include <stdio.h>
#include <string.h>

#define SIZE 50  // 定义目标数组的大小

int main(void) {

    const char src[] = "hello";  // 源字符串
    char dest[SIZE];  // 目标字符数组

    // 使用 strcpy_s 安全地将 src 复制到 dest
    strcpy_s(dest, SIZE, src);  

    // 输出源字符串和目标字符串
    printf("src: %s\n", src);   // 输出:hello
    printf("dest: %s\n", dest); // 输出:hello

    return 0;
}
3. 解释
  • const char src[] = "hello";:定义一个源字符串 src
  • char dest[SIZE];:定义一个大小为 SIZE 的目标字符数组 dest,它用于接收复制的内容。
  • strcpy_s(dest, SIZE, src);:使用 strcpy_ssrc 字符串的内容安全地复制到 dest 中。此函数会确保不会超出 dest 数组的边界,如果目标数组的大小不足以容纳源字符串,它会返回错误。
4. 输出
src: hello
dest: hello
5. 为什么使用 strcpy_s
  • strcpy_s 提供了额外的安全检查,防止了 strcpy 中可能发生的缓冲区溢出问题。
  • 使用 strcpy_s 时,必须指定目标缓冲区的大小,这样可以确保不会写入超出数组大小的内容。
  • 如果目标缓冲区太小,strcpy_s 不会执行任何复制操作,并且会返回一个错误码,确保程序的健壮性。
6. 注意事项
  • strcpy_s 是 C11 标准中定义的函数,某些编译器和平台可能不支持该函数,因此在一些环境中使用时需要确保它的可用性。如果不可用,可以使用其他方式进行安全的字符串复制。
  • strcpy_s 会修改目标数组,所以必须确保目标数组有足够的空间以容纳源字符串及其结束符 '\0'

194. gets_s 用法

gets_sgets 函数的安全版本,用于从标准输入获取字符串。gets 因为没有限制输入长度,容易导致缓冲区溢出问题,已经被 C11 标准废弃。gets_s 通过要求传入目标缓冲区的大小,防止了缓冲区溢出。

1. gets_s 函数原型:
errno_t gets_s(char *str, rsize_t size);
  • str:目标字符数组,用于存储用户输入的字符串。
  • size:目标字符数组的大小(以字符为单位)。
2. 代码示例
#include <stdio.h>
#include <string.h>

int main(void) {

    // 输出静态字符串
    const char* str = "Hello!";
    puts(str);  // 使用 puts 输出字符串

    // 创建字符数组缓冲区
    char buffer[100];

    // 提示用户输入
    printf("Enter a string: ");

    // 使用 gets_s 获取输入,并限制输入的大小
    gets_s(buffer, sizeof(buffer));

    // 输出用户输入的内容
    printf("You entered: %s\n", buffer);

    return 0;
}
3. 解释
  • puts(str):将静态字符串 "Hello!" 输出到标准输出(控制台)。
  • char buffer[100]:定义一个字符数组 buffer,用于存储用户输入的字符串。其大小为 100 字节。
  • gets_s(buffer, sizeof(buffer)):使用 gets_s 从用户获取输入,并将输入内容存储到 buffer 中。sizeof(buffer) 是缓冲区的大小,用来防止用户输入超过 buffer 大小的数据。
  • printf("You entered: %s\n", buffer);:输出用户输入的字符串。
4. 注意事项
  • gets_s 的使用可以有效防止缓冲区溢出,因为它要求提供目标缓冲区的大小。如果用户输入的数据超过缓冲区大小,gets_s 将不执行任何操作,返回错误。
  • 如果用户输入的内容包含 \n(换行符),gets_s 会自动将其替换为字符串结束符 \0,因此用户输入的字符串不会包含换行符。
5. gets_s 的错误处理

如果输入的字符串超出了目标缓冲区的大小,gets_s 会返回错误,并不会修改缓冲区内容。你可以根据需要进行错误处理。

if (gets_s(buffer, sizeof(buffer)) == NULL) {
    printf("Error or end of file encountered.\n");
} else {
    printf("You entered: %s\n", buffer);
}
6. 输出示例
Hello!
Enter a string: Hello, world!
You entered: Hello, world!
7. gets_sgets 的区别
  • 安全性gets 没有对输入的长度做任何限制,容易造成缓冲区溢出,导致程序崩溃或被恶意攻击。而 gets_s 要求指定缓冲区的大小,从而有效防止缓冲区溢出问题。
  • 废弃gets 在 C11 标准中已被废弃,而 gets_s 是 C11 标准中为提高安全性引入的替代方案。

因此,使用 gets_s 代替 gets 是一种更安全的编程实践。


204. 输入输出初步认识

在 C 语言中,输入和输出的处理是通过 输入流(input stream)输出流(output stream) 来实现的。通过这些流,程序能够与外部进行交互,例如读取用户输入或将结果输出到屏幕。

1. 输入流与输出流
  • 输入流:是从外部(通常是键盘或文件)读取数据的通道。在 C 语言中,标准输入通常表示为 stdin
  • 输出流:是将数据发送到外部的通道,通常是输出到显示器或文件。在 C 语言中,标准输出表示为 stdout
2. 缓冲区(Buffer)

缓冲区是一块内存区域,用于暂时存储输入或输出的数据。使用缓冲区能够提高输入输出操作的效率,减少频繁的硬件操作。

  • 输入缓冲区:当用户从键盘输入数据时,数据会首先存储在缓冲区中,直到程序显式地读取缓冲区中的内容。
  • 输出缓冲区:程序通过 printf 等函数将数据写入输出缓冲区,缓冲区中的内容在适当时机(例如缓冲区满时或程序结束时)才会被写到标准输出。
3. 标准输入(stdin)和标准输出(stdout
  • 标准输入(stdin:是程序接收输入的默认流。它通常指向键盘,用户通过键盘输入数据,程序从 stdin 中读取。
  • 标准输出(stdout:是程序输出数据的默认流。它通常指向屏幕,程序通过 stdout 将数据输出到屏幕上。
4. 示例代码:基本输入输出
#include <stdio.h>

int main(void) {
    // 使用 stdin 输入
    char name[50];
    printf("Enter your name: ");
    fgets(name, sizeof(name), stdin);  // 使用 fgets 替代 gets 防止缓冲区溢出

    // 使用 stdout 输出
    printf("Hello, %s!\n", name);

    return 0;
}
5. 解释
  • fgets(name, sizeof(name), stdin);:从标准输入(键盘)读取一行字符串,fgets 会自动将输入的换行符(\n)存储在字符串中,并且它不会发生缓冲区溢出。
  • printf("Hello, %s!\n", name);:将用户输入的名字输出到屏幕,%s 格式化符用于输出字符串。
6. 流的特点
  • 缓冲区的作用:缓冲区的使用可以提高 I/O 操作的效率。尤其在处理大量数据时,缓冲区能够将数据一次性批量读取或写入,减少了每次 I/O 操作的开销。
  • 自动刷新与手动刷新
    • stdout 在某些情况下(例如遇到换行符)会自动刷新缓冲区。
    • 如果需要手动刷新,可以使用 fflush(stdout);
7. 标准库中的输入输出函数
  • printf:将数据输出到标准输出。
  • scanf:从标准输入读取数据。
  • fgets:从标准输入读取一行数据(比 scanf 更安全,防止缓冲区溢出)。
  • fputs:将字符串输出到指定文件流。
  • freadfwrite:用于二进制数据的文件读取和写入。
8. 总结

输入输出流是程序与外部世界交互的桥梁,通过缓冲区提升数据处理的效率。理解 stdinstdout 的概念,以及如何使用不同的函数进行输入输出操作,能够帮助开发者写出更加高效和安全的程序。


206. scanf_s 返回值

在 C 语言中,scanf_s 是一个更安全的输入函数,通常用于替代 scanf。与 scanf 类似,scanf_s 用来从标准输入流(通常是键盘)中读取数据。与 scanf 一样,scanf_s 也会返回一个整数,表示成功读取的项数。

scanf_s 返回值:
  • 返回值为 1:表示成功读取一个项(例如一个整数、浮点数或字符)并将其存储到对应的变量中。
  • 返回值为 EOF(通常为 -1:表示读取操作失败,通常是因为遇到输入流的结束(如文件末尾或用户输入了不合法的数据)。
  • 返回值为其他正整数:表示成功读取多个项。
示例代码解释:
#include <stdio.h>

// 206. scanf_s返回值
int main(void) {

    int number;
    int result;

    puts("Enter an integer:");

    // 读取一个整数,并将其存储到 number 变量中
    result = scanf_s("%d", &number);

    if (result == 1) {
        // 如果成功读取一个整数
        printf("You entered the integer: %d\n", number);
    }
    else if (result == EOF) {
        // 如果遇到文件末尾或读取错误
        printf("An error occurred or end file was reached.\n");
        return 1;
    }
    else {
        // 如果输入不合法
        printf("Invalid input for integer.\n");
        return 1;
    }

    return 0;
}
代码解释:
  1. 读取输入
    • scanf_s("%d", &number); 会尝试从标准输入读取一个整数。%d 格式说明符表示整数。
    • 读取成功时,scanf_s 会返回读取的项数(在本例中为 1),并且输入的整数会存储在 number 中。
  2. 处理返回值
    • result == 1:表示成功读取了一个整数,程序会输出该整数。
    • result == EOF:表示遇到输入流的结束(如文件结束或者输入错误),会输出错误信息并退出程序。
    • 其他情况:如果输入的不是有效的整数(如用户输入了字母或其他无效字符),scanf_s 会返回 0,程序会输出“Invalid input for integer.”并退出。
常见问题:
  1. scanf_sscanf 的区别
    • scanf_s 是 Microsoft 提供的安全版本,它需要在读取字符串时指定最大输入长度来避免缓冲区溢出。而 scanf 并没有这种强制要求。
    • scanf_s 不仅对字符串处理有更多要求,且通常在 Windows 平台中使用。
  2. 输入错误处理
    • scanf_s 在读取输入时可能会遇到错误(例如用户输入了非数字字符)。这时,scanf_s 会返回 0,并且对应的变量不会被修改。为了避免程序出错,通常会在读取数据后检查返回值。
总结:

scanf_s 是一个比 scanf 更安全的输入函数,通过检查其返回值,我们能够确保输入是否成功,并且能够处理文件结束或输入错误的情况。


208. 使用 fopen_s, fgetc, fgets, fclose 读取文件

代码解析:

在这个示例中,程序展示了如何使用文件操作函数来读取文件内容。在 C 语言中,打开文件、读取文件和关闭文件是常见的操作。这里的重点是:

  • fopen_s: 用于打开文件。
  • fgetc: 逐个字符读取文件。
  • fgets: 按行读取文件。
  • fclose: 关闭文件。
代码实现:
#include <stdio.h>
#include <inttypes.h>
#include <stdlib.h>
#include <errno.h>

// 208. fopen_s, fgetc, fgets, fclose读取r模式  r模式:read读
int main(void) {

    FILE* file_stream = NULL; // 文件流

    char buffer[256];

    // 打开文件,设定文件路径要读取的文件,设定文件的操作模式r
    errno_t err = fopen_s(&file_stream, "C:\\Users\\86157\\Desktop\\123.txt", "r");

    // 检查文件是否成功打开
    if (err != 0 || file_stream == NULL) {
        perror("Error opening file");
        return EXIT_FAILURE;
    }

    // 使用 fgetc 一个一个地读取字符
    int ch;
    while ((ch = fgetc(file_stream)) != EOF) {
        putchar(ch);  // 将每个字符打印到标准输出
    }

    // 关闭文件流
    fclose(file_stream);

    return 0;
}
代码解释:
  1. 文件打开

    • fopen_s(&file_stream, "C:\\Users\\86157\\Desktop\\123.txt", "r");
      
      fopen_s
      

      是一种安全的文件打开方式,它比传统的

      fopen
      

      更加安全,能够处理潜在的错误(例如文件无法打开)。

      • file_stream: 是一个 FILE* 类型的文件指针,用来保存文件流。
      • "C:\\Users\\86157\\Desktop\\123.txt": 文件路径,可以是相对路径或绝对路径。
      • "r": 读模式,表示文件以只读方式打开。
  2. 文件打开失败处理

    • 如果 fopen_s 返回值不为 0file_streamNULL,说明文件打开失败,程序通过 perror 打印错误信息并退出。
  3. 逐字符读取文件

    • fgetc(file_stream) 逐个字符读取文件,直到遇到文件末尾(EOF)。
    • 每读取一个字符,putchar(ch) 会将字符打印到标准输出。
  4. 文件关闭

    • 使用 fclose(file_stream) 关闭文件,以释放文件流资源。
fopen_s, fgetc, fgets, 和 fclose 的用法:
  • fopen_s: 安全地打开文件。返回 0 表示成功,非零表示错误。
  • fgetc: 从文件中读取一个字符,直到遇到 EOF。
  • fgets: 一次读取一行内容,可以用来读取较长的文本行。它比 fgetc 更方便用于处理多行文本。
  • fclose: 关闭文件流,确保文件资源被正确释放。
示例输出:

假设 C:\\Users\\86157\\Desktop\\123.txt 文件内容如下:

Hello, world!
This is a test file.

程序输出会是:

Hello, world!
This is a test file.
fgets 示例:

如果需要按行读取文件,可以使用 fgets,它可以一次性读取一行内容。示例如下:

// 使用 fgets 读取文件每行
while (fgets(buffer, sizeof(buffer), file_stream) != NULL) {
    printf("%s", buffer);
}

这种方式会比 fgetc 更方便,尤其是在处理较长的文件时。


209. 使用 fputs, fputcw 模式写文件

代码解析:

在这个示例中,程序展示了如何使用文件操作函数来写入数据到文件。在 C 语言中,常用的写文件操作函数包括:

  • fputc: 用于将一个字符写入文件。
  • fputs: 用于将一个字符串写入文件。
  • fprintf_s: 用于将格式化的数据写入文件。

文件以 w 模式打开,这表示以写入模式打开文件。如果文件已经存在,会被覆盖;如果文件不存在,会创建新文件。

代码实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <inttypes.h>

// 209. fputs, fputc与w模式
int main(void) {

    FILE* file_ptr = NULL;

    // 打开文件,w模式:write,写入模式
    errno_t err = fopen_s(&file_ptr, "C:\\Users\\86157\\Desktop\\123.txt", "w");

    // 检查文件是否成功打开
    if (err != 0 || file_ptr == NULL) {
        perror("Failed to open file");
        return EXIT_FAILURE;
    }

    // 使用 fputc() 写入字符
    fputc('H', file_ptr);   // 写入字符 'H'
    fputc('i', file_ptr);   // 写入字符 'i'
    fputc('\n', file_ptr);  // 写入换行符

    // 使用 fputs() 写入字符串
    fputs("This is a line written by fputs.\n", file_ptr);

    // 使用 fprintf_s() 写入格式化内容
    double pi = 3.14;
    fprintf_s(file_ptr, "Numbers: %d, %lf, %s\n", 10, pi, "End of example");

    // 关闭文件
    fclose(file_ptr);

    // 输出成功信息
    puts("File '123.txt' has been written successfully.\n");

    return 0;
}
代码解释:
  1. 打开文件

    • fopen_s(&file_ptr, "C:\\Users\\86157\\Desktop\\123.txt", "w")
      

      :以

      w
      

      模式打开文件。

      • w 模式表示写入模式,文件内容会被完全覆盖。如果文件不存在,将会创建新文件。
      • file_ptr 是文件指针,用于操作打开的文件。
  2. 写入字符

    • fputc('H', file_ptr):写入字符 ‘H’。
    • fputc('i', file_ptr):写入字符 ‘i’。
    • fputc('\n', file_ptr):写入换行符。
  3. 写入字符串

    • fputs("This is a line written by fputs.\n", file_ptr):写入字符串。
  4. 格式化输出

    • fprintf_s(file_ptr, "Numbers: %d, %lf, %s\n", 10, pi, "End of example"):写入格式化字符串(整数、浮点数和字符串)。
  5. 关闭文件

    • fclose(file_ptr):关闭文件,释放文件资源。
  6. 文件写入成功提示

    • puts("File '123.txt' has been written successfully.\n"):输出文件写入成功的提示信息。
写入模式说明:
  • w模式:会重写文件内容,若文件已存在则清空内容;若文件不存在,则创建新文件。
  • fputc:逐个字符写入文件。
  • fputs:将字符串写入文件,直到遇到空字符 \0
  • fprintf_s:类似 printf,但写入到文件中,支持格式化输出。
示例输出文件内容:

假设文件 123.txt 最终的内容如下:

Hi
This is a line written by fputs.
Numbers: 10, 3.140000, End of example
注意事项:
  1. fopen_s 函数返回 errno_t 类型,表示打开文件时是否出错。如果文件打开失败,程序会通过 perror 输出错误信息。
  2. 使用 fputcfputsfprintf_s 时,确保文件是以正确的模式打开的。
  3. 在使用文件操作时,记得调用 fclose 关闭文件,以释放文件句柄。

这段代码演示了如何通过不同方式将数据写入文件,使用了 C 标准库中的多种文件输出函数,并确保文件在操作后被正确关闭。


218. 游戏设置案例:二进制文件存储与读取

错误分析:

在你的代码中,有两个问题导致报错:

  1. 拼写错误: 在 save_game_settings 函数中,fwirte 应该是 fwritefwrite 是标准库中的一个函数,用于将数据写入文件。
  2. fwritefread 参数的问题fwritefread 函数的使用是正确的,但需要确保操作的是一个有效的文件指针,并且需要正确指定读取和写入的数据量。
修正后的代码:
#include <stdio.h>
#include <stdlib.h>

// 游戏设置结构体
typedef struct GameSettings {
    float volume;        // 音量
    int resolution_x;    // 分辨率X
    int resolution_y;    // 分辨率Y
    int difficulty;      // 难度
} GameSettings;

// 函数声明
void save_game_settings(const GameSettings* settings, const char* filename);
void load_game_settings(GameSettings* settings, const char* filename);

int main(void) {

    // 游戏设置实例
    GameSettings settings = { 0.75, 1920, 1080, 2 };

    // 保存游戏设置到二进制文件
    save_game_settings(&settings, "C:\\Users\\86157\\Desktop\\game_settings.bin");

    GameSettings loaded_settings;

    // 从二进制文件读取游戏设置
    load_game_settings(&loaded_settings, "C:\\Users\\86157\\Desktop\\game_settings.bin");

    printf("游戏设置已经加载!\n");
    printf("音量:%f\n分辨率:%dx%d\n难度:%d\n", loaded_settings.volume, loaded_settings.resolution_x, loaded_settings.resolution_y, loaded_settings.difficulty);

    return 0;
}

// 保存游戏设置到二进制文件
void save_game_settings(const GameSettings* settings, const char* filename) {
    FILE* file;
    // 使用wb模式打开文件进行写入
    errno_t err = fopen_s(&file, filename, "wb");
    if (err != 0 || file == NULL) {
        perror("无法打开文件进行写入操作");
        return;
    }

    // 写入数据
    fwrite(settings, sizeof(GameSettings), 1, file);
    fclose(file);  // 关闭文件
}

// 从二进制文件读取游戏设置
void load_game_settings(GameSettings* settings, const char* filename) {
    FILE* file;
    // 使用rb模式打开文件进行读取
    errno_t err = fopen_s(&file, filename, "rb");
    if (err != 0 || file == NULL) {
        perror("无法打开文件进行读取操作");
        return;
    }

    // 读取数据
    fread(settings, sizeof(GameSettings), 1, file);
    fclose(file);  // 关闭文件
}

代码解释:

  1. 结构体定义
    • GameSettings 结构体包含了音量、分辨率和难度等设置项,用于存储游戏设置。
  2. 文件写入
    • save_game_settings 函数使用 fwriteGameSettings 结构体的内容写入到指定的二进制文件。
    • 打开文件时使用 "wb" 模式,这意味着以二进制方式写入文件。如果文件不存在,它将创建新文件;如果文件存在,它将覆盖文件内容。
  3. 文件读取
    • load_game_settings 函数使用 fread 从二进制文件读取数据到结构体中。
    • 打开文件时使用 "rb" 模式,这意味着以二进制方式读取文件。
  4. 错误检查
    • 如果文件无法打开(例如路径错误或没有访问权限),则使用 perror 输出错误信息。
  5. 文件关闭
    • 使用 fclose 关闭文件以释放资源。

主要函数:

  • fwrite:用于写入二进制数据到文件。

    size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream);
    
    • ptr: 指向要写入数据的内存块。
    • size: 每个元素的大小。
    • count: 写入的元素数量。
    • stream: 文件指针。
  • fread:用于从文件中读取二进制数据。

    size_t fread(void* ptr, size_t size, size_t count, FILE* stream);
    
    • ptr: 指向存储读取数据的内存块。
    • size: 每个元素的大小。
    • count: 读取的元素数量。
    • stream: 文件指针。

使用 "wb""rb" 模式:

  • wb:打开文件进行写入,如果文件已存在,清空文件内容。
  • rb:以二进制模式打开文件进行读取,文件必须存在。

常见问题和修复:

  1. 拼写错误fwirte 应该是 fwrite
  2. 路径错误:确保文件路径是正确的,并且程序有权限访问该文件。
  3. 数据类型问题:使用 sizeof(GameSettings) 来确保写入或读取的大小与结构体大小一致。

输出结果:

假设文件 game_settings.bin 存储了以下数据:

音量:0.750000
分辨率:1920x1080
难度:2

该程序可以正确地保存和加载游戏设置。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值