当前位置: 首页 > news >正文

c语言中比较特殊的输入函数

目录

一.getchar()函数

1.基本功能

2.使用方法

(1).读取单个字符

(2).读取多个字符(直到遇到换行符)

(3).处理输入中的空白字符

3.返回值

4.应用场景

5.注意事项

二.fgets()函数

1.函数原型

2.工作原理

3.使用示例

(1).从标准输入读取一行字符串

(2).从文件中读取内容

4.处理换行符

5.与其他输入函数的比较

(1). fgets vs gets

(2). fgets vs scanf

(3). fgets vs fgetc

6、常见错误和注意事项

(1). 忘记检查返回值

(2). 未正确处理换行符

(3). 缓冲区大小不足

(4). 多次读取时的缓冲区残留

7.综合示例

三.sscanf函数

1.函数原型

2.工作原理

(1).从字符串中解析数据

3.常见用法和注意事项

(1). 解析特定格式的字符串

(2). 处理多余的输入

(3). 不匹配的格式

(4). 忽略特定数据

(5). 返回值处理

4.常见错误和陷阱

(1). 未匹配到预期的数据

(2). 忘记检查返回值

(3). 缓冲区溢出

(4). 处理多余输入

5.sscanf 与其他输入函数的比较

(1). sscanf vs scanf

(2). sscanf vs fscanf

(3). sscanf vs strtok

6.综合示例

四.fscanf()函数

1.函数原型

2.工作原理

3.常用用法和注意事项

(1). 读取一行数据

(2). 文件指针位置

(3). 遇到EOF

(4). 忽略特定数据

(5). 返回值处理

(6). 处理多余输入

4.常见错误和陷阱

(1). 格式不匹配

(2). 忘记检查返回值

(3). 文件结束符

5.fscanf 与其他输入函数的比较

(1). fscanf vs scanf

(2). fscanf vs sscanf

(3). fscanf vs fgets

6.综合示例


一.getchar()函数

getchar()是C语言中的一个标准库函数,用于从标准输入(通常是键盘)读取一个字符。它是stdio.h库的一部分,常用于简单的字符输入操作。

1.基本功能

getchar()读取标准输入中的下一个字符,并将其作为一个int类型的值返回。尽管返回值是int类型,但它实际上是一个字符的ASCII值

2.使用方法

int ch = getchar();

在这段代码中,getchar()从标准输入中读取一个字符,并将其返回的字符值存储在ch变量中。

示例:

(1).读取单个字符

#include <stdio.h>int main() {int ch;printf("请输入一个字符: ");ch = getchar();printf("你输入的字符是: %c\n", ch);return 0;
}

解释:

  • 程序等待用户输入一个字符。用户输入的字符被getchar()读取并存储在ch中。
  • printf函数随后输出用户输入的字符。

(2).读取多个字符(直到遇到换行符)

#include <stdio.h>int main() {int ch;printf("请输入一行文字,按回车结束: ");while ((ch = getchar()) != '\n' && ch != EOF) {printf("读取字符: %c\n", ch);}printf("输入结束。\n");return 0;
}

解释:

  • 程序使用while循环来读取字符,直到遇到换行符('\n')或文件结束符(EOF)。
  • 每次读取的字符都会被输出。

(3).处理输入中的空白字符

#include <stdio.h>int main() {int ch;printf("请输入字符,输入结束请按 Ctrl+D (Linux) 或 Ctrl+Z (Windows):\n");while ((ch = getchar()) != EOF) {if (ch == ' ' || ch == '\n' || ch == '\t') {printf("[空白字符]\n");} else {printf("读取字符: %c\n", ch);}}printf("输入结束。\n");return 0;
}

解释:

  • 这个程序读取用户输入的每个字符,并检查它是否是空白字符(空格、换行符、制表符)。
  • 如果是空白字符,程序会输出[空白字符],否则输出字符本身。
  • 当用户按下Ctrl+DCtrl+Z时,输入结束。

3.返回值

  • 读取的字符: 如果读取成功,getchar()返回读取的字符的ASCII值。例如,如果用户输入字符'A'getchar()将返回值65(即'A'的ASCII码)。

  • EOF (End of File): 如果在读取时遇到文件结束符(通常是在控制台输入时按下Ctrl+DCtrl+Z),getchar()将返回常量EOF,其值通常为-1EOF用于指示输入的结束或错误情况。

4.应用场景

  • 简单字符输入: getchar()通常用于简单的字符输入操作,例如读取单个字符或控制台中的用户输入。

  • 处理空白字符: 当你需要明确处理空白字符(例如空格、制表符或换行符)时,getchar()特别有用。相比于scanfgetchar()不会跳过空白字符,因此你可以逐字符地处理输入。

  • 控制输入流: getchar()在处理输入流时非常灵活,可以用于跳过不需要的字符。例如,在多行输入或复杂输入格式的情况下,它可以帮助你控制和过滤输入内容。

5.注意事项

  • 返回类型为int: 尽管getchar()用于读取单个字符,但它的返回类型是int而不是char。这样设计是为了能够返回EOF来表示文件结束或错误。为了避免潜在的错误,通常应该使用int类型来存储getchar()的返回值。

  • 缓冲区问题: 在控制台输入时,用户输入的内容通常会先进入缓冲区。当按下回车键时,缓冲区中的内容才会被getchar()逐个读取。因此,getchar()不会在每个字符输入时立即返回,而是等待用户按下回车键。

  • 错误处理: 当使用getchar()时,程序应该考虑EOF的可能性,尤其是在文件输入或批处理输入的情况下。忽略这一点可能会导致程序未正确处理输入结束的情况。

二.fgets()函数

fgets 是C语言中用于从文件流中读取一行字符串的标准库函数。它提供了一种安全、方便的方法来读取输入,避免了诸如缓冲区溢出等常见问题。fgets 通常用于读取用户输入、从文件中读取数据等场景。

1.函数原型

char *fgets(char *str, int n, FILE *stream);

  • str: 指向字符数组的指针,fgets 会将读取到的字符串存储在该数组中。
  • n: 要读取的最大字符数,包括结尾的空字符 \0。也就是说,fgets 最多读取 n-1 个字符。
  • stream: 输入流指针,指明从哪个流中读取数据。常见的流有标准输入流 stdin,文件流等。

返回值

  • 成功: 返回指向读取字符串的指针,即参数 str
  • 失败或到达文件末尾: 返回 NULL

2.工作原理

fgets 函数从指定的输入流 stream 中读取字符,并将其存储到 str 指向的字符数组中,直到发生以下任一情况:

  1. 读取了 (n - 1) 个字符: 为了保证字符串以 \0 结尾,fgets 最多读取 n - 1 个字符。
  2. 遇到换行符 \n: fgets 会读取换行符,并将其存储在 str 中。
  3. 到达文件末尾 EOF: 如果在读取过程中遇到文件末尾,读取操作结束。

读取完成后,fgets 会在读取的字符串末尾自动添加一个空字符 \0,以表示字符串的结束。

3.使用示例

(1).从标准输入读取一行字符串

#include <stdio.h>int main() {char buffer[100];printf("请输入一行文本:");if (fgets(buffer, sizeof(buffer), stdin) != NULL) {printf("您输入的是:%s", buffer);} else {printf("读取输入时发生错误。\n");}return 0;
}

解释:

  • fgets(buffer, sizeof(buffer), stdin) 从标准输入读取最多 99 个字符(保留1个字符给 \0),并存储在 buffer 中。
  • 如果读取成功,程序会输出用户输入的内容。

注意: 由于 fgets 会将换行符 \n 一并读取并存储,如果不想要这个换行符,需要手动去除。

(2).从文件中读取内容

#include <stdio.h>int main() {FILE *fp = fopen("example.txt", "r");if (fp == NULL) {perror("无法打开文件");return 1;}char line[256];while (fgets(line, sizeof(line), fp) != NULL) {printf("%s", line);}fclose(fp);return 0;
}

解释:

  • 打开名为 example.txt 的文件,读取其中的内容并逐行打印到标准输出。
  • fgets 在每次循环中读取一行内容,直到文件结束。

4.处理换行符

正如前面提到的,fgets 会将输入中的换行符 \n 一并读取并存储在目标字符串中。如果在处理时不需要这个换行符,可以使用以下方法去除:

方法1:手动检查并替换

size_t len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n') {buffer[len - 1] = '\0';
}

解释:

  • 首先获取字符串的长度 len
  • 如果最后一个字符是 \n,将其替换为 \0

方法2:使用 strcspn 函数

buffer[strcspn(buffer, "\n")] = '\0';

解释:

  • strcspn 函数返回 buffer 中第一个匹配 \n 的位置索引,然后将该位置的字符替换为 \0

5.与其他输入函数的比较

(1). fgets vs gets

  • gets: 从标准输入读取一行,直到遇到换行符或文件结束符。不安全,因为无法指定读取的最大长度,容易导致缓冲区溢出。

  • fgets: 可以指定最大读取长度,安全性更高。建议始终使用 fgets 代替 gets

(2). fgets vs scanf

  • scanf: 按照指定的格式从输入中读取数据,默认会忽略空白字符,读取字符串时会在遇到空白字符时停止。

  • fgets: 读取整行输入,包括空白字符和换行符,更适合读取包含空格的字符串

示例:

char str1[100], str2[100];// 使用 scanf
scanf("%s", str1);
// 输入:Hello World
// str1 的值为:"Hello"// 使用 fgets
fgets(str2, sizeof(str2), stdin);
// 输入:Hello World
// str2 的值为:"Hello World\n"

(3). fgets vs fgetc

  • fgetc: 每次从指定流中读取一个字符,适合逐字符处理输入。

  • fgets: 一次读取一行或指定长度的字符串,效率更高。

6、常见错误和注意事项

(1). 忘记检查返回值

在使用 fgets 时,应该始终检查其返回值,以确保读取成功。

错误示例:

fgets(buffer, sizeof(buffer), stdin);
// 未检查返回值,可能导致程序处理空指针

正确示例:

if (fgets(buffer, sizeof(buffer), stdin) != NULL) {// 处理读取的数据
} else {// 错误处理
}

(2). 未正确处理换行符

如前所述,fgets 会保留输入中的换行符,如果不想要这个换行符,需要手动去除。

(3). 缓冲区大小不足

确保提供给 fgets 的缓冲区足够大,以容纳预期的输入数据和结尾的空字符。

错误示例:

char buffer[10];
fgets(buffer, 100, stdin); // 错误:缓冲区只有10个字节,却试图读取100个字符

正确示例:

char buffer[100];
fgets(buffer, sizeof(buffer), stdin); // 正确:缓冲区大小与读取长度匹配

(4). 多次读取时的缓冲区残留

在某些情况下,输入流中可能残留未读取的字符,需要在下一次读取前清空缓冲区。

char buffer1[50], buffer2[50];printf("输入第一行:");
fgets(buffer1, sizeof(buffer1), stdin);printf("输入第二行:");
fgets(buffer2, sizeof(buffer2), stdin);

如果在第一次输入时输入的字符超过了 buffer1 的大小,剩余的字符会留在输入缓冲区中,影响第二次读取。为避免这种情况,可以在每次读取后清空缓冲区。

清空缓冲区的方法:

int c;
while ((c = getchar()) != '\n' && c != EOF);

7.综合示例

示例:读取用户输入并处理

#include <stdio.h>
#include <string.h>int main() {char name[50];int age;char input[100];// 读取姓名printf("请输入您的姓名:");if (fgets(name, sizeof(name), stdin) != NULL) {// 去除换行符name[strcspn(name, "\n")] = '\0';} else {printf("读取姓名失败。\n");return 1;}// 读取年龄printf("请输入您的年龄:");if (fgets(input, sizeof(input), stdin) != NULL) {// 将字符串转换为整数age = atoi(input);} else {printf("读取年龄失败。\n");return 1;}printf("姓名:%s,年龄:%d\n", name, age);return 0;
}

解释:

  • 首先使用 fgets 读取用户的姓名,并去除结尾的换行符。
  • 然后再次使用 fgets 读取用户的年龄输入,并使用 atoi 将其转换为整数。
  • 最后输出用户输入的信息。

三.sscanf函数

sscanf 是C语言中用于从字符串中读取并解析数据的标准库函数。它的作用类似于 scanf,但 sscanf字符串中读取数据,而 scanf 是从标准输入中读取数据。sscanf 非常适合从已知格式的字符串中提取数值、字符等数据。

1.函数原型

int sscanf(const char *str, const char *format, ...);

  • str: 要解析的源字符串。sscanf 会从这个字符串中读取数据。
  • format: 格式字符串,指定了要解析的数据格式。它的语法和 scanf 的格式字符串相同,包括各种格式说明符(如 %d, %s, %f 等)。
  • ...: 可变参数列表,提供用于存储从字符串中读取的数据的指针。

返回值

  • 成功: 返回成功读取并匹配的项数
  • 失败: 返回 EOF,如果在解析过程中遇到错误或在尝试读取时到达字符串末尾

2.工作原理

sscanf 函数根据 format 字符串中的格式说明符,从源字符串 str 中逐一读取和解析数据。每个格式说明符都对应于一个传入的变量地址,sscanf 将解析后的数据存储在这些变量中。

格式说明符示例

  • %d: 读取一个整数。
  • %f: 读取一个浮点数。
  • %s: 读取一个字符串,遇到空白字符(如空格、换行)时停止。
  • %c: 读取单个字符。

示例:

(1).从字符串中解析数据

#include <stdio.h>int main() {const char *str = "100 3.14 hello";int num;float pi;char word[20];int count = sscanf(str, "%d %f %s", &num, &pi, word);printf("读取到 %d 项数据:\n", count);printf("整数: %d\n", num);printf("浮点数: %.2f\n", pi);printf("字符串: %s\n", word);return 0;
}

输出:

读取到 3 项数据:
整数: 100
浮点数: 3.14
字符串: hello

解释:

  • sscanf 解析字符串 "100 3.14 hello",并将数据分别存储在 num, pi, word 中。
  • 返回值 count 表示成功读取了3项数据。

3.常见用法和注意事项

(1). 解析特定格式的字符串

sscanf 特别适用于解析具有固定格式的字符串,比如日期、时间、IP地址等。

示例:解析日期

#include <stdio.h>int main() {const char *date = "2024-08-17";int year, month, day;sscanf(date, "%d-%d-%d", &year, &month, &day);printf("年: %d, 月: %d, 日: %d\n", year, month, day);return 0;
}

输出:

年: 2024, 月: 8, 日: 17

解释:

  • 解析字符串 "2024-08-17" 中的年份、月份和日期,并分别存储在 year, month, day 中。

(2). 处理多余的输入

如果源字符串中的内容多于格式说明符指定的内容,sscanf 只会处理指定的部分,忽略其余部分。

示例:部分解析字符串

#include <stdio.h>int main() {const char *str = "42 3.14 some extra text";int num;float pi;int count = sscanf(str, "%d %f", &num, &pi);printf("读取到 %d 项数据:\n", count);printf("整数: %d\n", num);printf("浮点数: %.2f\n", pi);return 0;
}

输出:

读取到 2 项数据:
整数: 42
浮点数: 3.14

解释:

  • sscanf 只解析了前两个数据项(整数和浮点数),忽略了字符串末尾的额外内容。

(3). 不匹配的格式

如果字符串中的内容与格式说明符不匹配,sscanf 会停止解析,并返回已成功读取的项数。

示例:格式不匹配

#include <stdio.h>int main() {const char *str = "hello 3.14";int num;float pi;int count = sscanf(str, "%d %f", &num, &pi);printf("读取到 %d 项数据:\n", count);return 0;
}

输出:

读取到 0 项数据:

(4). 忽略特定数据

sscanf 还可以使用 * 来忽略某些输入数据,不存储在任何变量中。

示例:忽略数据

#include <stdio.h>int main() {const char *str = "42 skip this 3.14";int num;float pi;sscanf(str, "%d %*s %f", &num, &pi);printf("整数: %d\n", num);printf("浮点数: %.2f\n", pi);return 0;
}

输出:

整数: 42
浮点数: 3.14

解释:

  • sscanf 使用 %*s 忽略了 "skip this" 字符串部分,只提取了整数和浮点数。

(5). 返回值处理

sscanf 的返回值用于检查是否成功解析了预期的项数。在实际编程中,应该根据返回值来验证解析操作的成功与否。

示例:检查返回值

#include <stdio.h>int main() {const char *str = "100 3.14";int num;float pi;int result = sscanf(str, "%d %f", &num, &pi);if (result == 2) {printf("成功读取两个数值:%d 和 %.2f\n", num, pi);} else {printf("解析失败,已成功读取 %d 项数据。\n", result);}return 0;
}

输出:

成功读取两个数值:100 和 3.14

解释:

  • 如果 sscanf 成功解析了两个值,程序输出成功消息。否则,输出失败消息。

4.常见错误和陷阱

(1). 未匹配到预期的数据

如果输入字符串的格式与格式说明符不匹配,sscanf 会停止解析,返回已经成功解析的项数。确保格式字符串与输入字符串的格式一致非常重要。

(2). 忘记检查返回值

忽略 sscanf 的返回值可能导致错误的程序行为。检查返回值是验证解析操作成功与否的关键步骤。

(3). 缓冲区溢出

当读取字符串数据(如使用 %s)时,确保目标缓冲区有足够的空间以避免溢出。使用长度限制格式符号(如 %99s)可以防止缓冲区溢出。

(4). 处理多余输入

如果 sscanf 只读取了部分输入数据,而程序的逻辑依赖于完整的数据解析,可能会导致问题。合理设计格式说明符和字符串输入非常重要。

5.sscanf 与其他输入函数的比较

(1). sscanf vs scanf

  • scanf: 从标准输入中读取数据,适用于直接的用户输入操作。

  • sscanf: 从字符串中读取数据,适用于解析已经存在的字符串内容。

(2). sscanf vs fscanf

  • fscanf: 从文件流中读取数据,适用于从文件中解析数据。

  • sscanf: 从字符串中读取数据,适用于解析内存中的字符串。

(3). sscanf vs strtok

  • strtok: 用于分割字符串,可以按指定的分隔符逐一提取子字符串。

  • sscanf: 直接解析字符串中的数据,并将其转换为相应的数据类型。

6.综合示例

示例:解析复杂字符串

#include <stdio.h>int main() {const char *str = "Name: John Doe, Age: 30, Score: 85.5";char name[50];int age;float score;int count = sscanf(str, "Name: %[^,], Age: %d, Score: %f", name, &age, &score);if (count == 3) {printf("姓名: %s\n", name);printf("年龄: %d\n", age);printf("分数: %.1f\n", score);} else {printf("解析字符串失败。\n");}return 0;
}

输出:

姓名: John Doe
年龄: 30
分数: 85.5

解释:

  • 使用 sscanf 从格式化字符串中提取姓名、年龄和分数。%[^,] 格式说明符用于读取直到遇到逗号 , 的所有字符,这样可以处理包含空格的姓名。

四.fscanf()函数

fscanf 是C语言中用于从文件读取并解析数据的标准库函数。它的作用类似于 scanf,但 fscanf 从文件流中读取数据,而 scanf从标准输入中读取数据fscanf 适合从文件中逐行或逐项读取并解析数据。

1.函数原型

int fscanf(FILE *stream, const char *format, ...);

参数说明

  • stream: 文件指针,指向要读取的文件流(通常是通过 fopen 打开的文件)。
  • format: 格式字符串,指定了要解析的数据格式。它的语法和 scanf 的格式字符串相同,包括各种格式说明符(如 %d, %s, %f 等)。
  • ...: 可变参数列表,提供用于存储从文件中读取的数据的指针。

返回值

  • 成功: 返回成功读取并匹配的项数
  • 失败: 如果遇到文件结束符 EOF,则返回 EOF。如果遇到错误,返回负数。

2.工作原理

fscanf 函数根据 format 字符串中的格式说明符,从文件流 stream 中逐一读取和解析数据。每个格式说明符都对应于一个传入的变量地址,fscanf 将解析后的数据存储在这些变量中。

格式说明符示例

  • %d: 读取一个整数。
  • %f: 读取一个浮点数。
  • %s: 读取一个字符串,遇到空白字符(如空格、换行)时停止。
  • %c: 读取单个字符。

示例:从文件中解析数据

假设有一个文本文件 data.txt,内容如下:

42 3.14 hello
#include <stdio.h>int main() {FILE *file = fopen("data.txt", "r"); // 打开文件进行读取if (file == NULL) {perror("无法打开文件");return 1;}int num;float pi;char word[20];int count = fscanf(file, "%d %f %s", &num, &pi, word);printf("读取到 %d 项数据:\n", count);printf("整数: %d\n", num);printf("浮点数: %.2f\n", pi);printf("字符串: %s\n", word);fclose(file); // 关闭文件return 0;
}

输出:

读取到 3 项数据:
整数: 42
浮点数: 3.14
字符串: hello

解释:

  • fscanf 从文件 data.txt 中解析数据,并将数据分别存储在 num, pi, word 中。
  • 返回值 count 表示成功读取了3项数据。

3.常用用法和注意事项

(1). 读取一行数据

fscanf 通常按格式说明符读取数据,直到匹配结束,或者遇到文件结束符 EOF。它不会自动处理行结束符,因此如果要按行读取数据,可以结合 fgetssscanf 使用。

示例:逐行读取数据

假设文件 data.txt 内容如下:

42 3.14 hello
43 2.71 world
#include <stdio.h>int main() {FILE *file = fopen("data.txt", "r");if (file == NULL) {perror("无法打开文件");return 1;}int num;float pi;char word[20];while (fscanf(file, "%d %f %s", &num, &pi, word) != EOF) {printf("整数: %d, 浮点数: %.2f, 字符串: %s\n", num, pi, word);}fclose(file);return 0;
}

输出:

整数: 42, 浮点数: 3.14, 字符串: hello
整数: 43, 浮点数: 2.71, 字符串: world

(2). 文件指针位置

fscanf 读取数据后,文件指针会移动到读取结束的位置。下一次调用 fscanf 会从当前文件指针位置继续读取。

(3). 遇到EOF

fscanf 遇到文件结束符 EOF 时,它会返回 EOF,通常是 -1。这可以用来判断是否已经读取到文件末尾。

(4). 忽略特定数据

类似于 sscanffscanf 也可以使用 * 来忽略某些输入数据,而不存储在任何变量中。

示例:忽略数据

#include <stdio.h>int main() {FILE *file = fopen("data.txt", "r");if (file == NULL) {perror("无法打开文件");return 1;}int num;float pi;while (fscanf(file, "%d %*s %f", &num, &pi) != EOF) {printf("整数: %d, 浮点数: %.2f\n", num, pi);}fclose(file);return 0;
}

解释:

  • fscanf 使用 %*s 忽略了字符串部分,只提取了整数和浮点数。

(5). 返回值处理

sscanf 类似,fscanf 的返回值表示成功读取并解析的数据项数。在实际编程中,应该根据返回值来验证解析操作的成功与否。

示例:检查返回值

#include <stdio.h>int main() {FILE *file = fopen("data.txt", "r");if (file == NULL) {perror("无法打开文件");return 1;}int num;float pi;while (fscanf(file, "%d %f", &num, &pi) == 2) { // 期望成功读取2项数据printf("整数: %d, 浮点数: %.2f\n", num, pi);}fclose(file);return 0;
}

解释:

  • 只有在成功解析了两个值时才输出结果。如果 fscanf 未能成功读取两个值,将停止读取。

(6). 处理多余输入

如果文件中的内容多于格式说明符指定的内容,fscanf 只会处理指定的部分,忽略其余部分。

4.常见错误和陷阱

(1). 格式不匹配

如果文件中的内容与格式说明符不匹配,fscanf 会停止解析,并返回已成功读取的项数。确保格式字符串与文件内容格式一致非常重要。

(2). 忘记检查返回值

忽略 fscanf 的返回值可能导致错误的程序行为。检查返回值是验证解析操作成功与否的关键步骤。

(3). 文件结束符

fscanf 在读取到文件结束符 EOF 时会返回 EOF,这与常规的返回值检查不同,处理文件结束符时需要特别注意。

5.fscanf 与其他输入函数的比较

(1). fscanf vs scanf

  • scanf: 从标准输入中读取数据,适用于直接的用户输入操作。

  • fscanf: 从文件流中读取数据,适用于从文件中解析数据。

(2). fscanf vs sscanf

  • sscanf: 从字符串中读取数据,适用于解析内存中的字符串。

  • fscanf: 从文件流中读取数据,适用于从文件中解析数据。

(3). fscanf vs fgets

  • fgets: 从文件中读取一整行字符串,适用于逐行读取文件内容,通常结合 sscanf 使用以进一步解析数据。

  • fscanf: 按照格式说明符从文件中读取数据,适用于逐项解析数据。

6.综合示例

示例:从文件中读取并解析数据

假设有一个文本文件 students.txt,内容如下:

John 20 85.5
Alice 22 90.0
Bob 21 78.5
#include <stdio.h>int main() {FILE *file = fopen("students.txt", "r");if (file == NULL) {perror("无法打开文件");return 1;}char name[50];int age;float score;while (fscanf(file, "%s %d %f", name, &age, &score) == 3) {printf("姓名: %s, 年龄: %d, 分数: %.1f\n", name, age, score);}fclose(file);return 0;
}

输出

姓名: John, 年龄: 20, 分数: 85.5
姓名: Alice, 年龄: 22, 分数: 90.0
姓名: Bob, 年龄: 21, 分数: 78.5

解释:

  • fscanf 从文件 students.txt 中解析每一行数据,并输出到屏幕上。它通过格式说明符 %s %d %f 解析每行中的姓名、年龄和分数。

完!

一键三连支持一下吧,非常感谢!

相关文章:

c语言中比较特殊的输入函数

目录 一.getchar()函数 1.基本功能 2.使用方法 (1).读取单个字符 (2).读取多个字符&#xff08;直到遇到换行符&#xff09; (3).处理输入中的空白字符 3.返回值 4.应用场景 5.注意事项 二.fgets()函数 1.函数原型 2.工作原理 3.使用示例 (1).从标准输入读取一行…...

Java版自动化测试之Selenium

1. 准备 编程语言&#xff1a;Java JDK版本&#xff1a;17 Maven版本&#xff1a;3.6.1 2. 开始 声明&#xff1a;本次只测试Java的Selenium自动化功能 本次示例过程&#xff1a;打开谷歌游览器&#xff0c;进入目标网址&#xff0c;找到网页的输入框元素&#xff0c;输入指…...

【计算机网络】——计算机网络的性能指标

速率&#xff08;speed&#xff09; 连接在计算机网络上的主机在数字信道上传送数据的速率。 影响条件&#xff1a; 带宽&#xff08;band width&#xff09; 指在固定的时间可传输的资料数量 单位&#xff1a;bps或HZ 吞吐量&#xff08;throughtput&#xff09; 指对网络、…...

MongoDB数据类型介绍

MongoDB作为一种高性能、开源、无模式的文档型数据库&#xff0c;支持丰富的数据类型&#xff0c;以满足各种复杂的数据存储需求。本文将详细介绍MongoDB支持的主要数据类型&#xff0c;包括数值类型、字符串类型、日期和时间类型、布尔类型、二进制类型、数组、对象以及其他扩…...

【SpringBoot】SpringBoot 中 Bean 管理和拦截器的使用

目录 1.Bean管理 1.1 自定义Bean对象 1.2 Bean的作用域和生命周期 2.拦截器的使用 1.Bean管理 默认情况下&#xff0c;Spring项目启动时&#xff0c;会把我们常用的Bean都创建好放在IOC容器中&#xff0c;但是有时候我们自定义的类需要手动配置bean&#xff0c;这里主要介绍…...

Spring IoCDI(中)--IoC的进步

通过上文的讲解和学习, 我们已经知道了Spring IoC 和DI的基本操作, 接下来我们来系统的学习Spring IoC和DI 的操作. 前⾯我们提到IoC控制反转&#xff0c;就是将对象的控制权交给Spring的IOC容器&#xff0c;由IOC容器创建及管理对 象&#xff0c;也就是bean的存储。 1. Bean的…...

读软件开发安全之道:概念、设计与实施02经典原则

1. CIA原则 1.1. 软件安全都构建在信息安全的三大基本原则之上&#xff0c;即机密性(confidentiality)、完整性(integrity)和可用性(availability) 1.2. 双方交换的数据 1.2.1. 从技术上看&#xff0c;端点之间的数据交换本身就会削弱交互的机密性 1.2.2. 隐藏通信数据量的一…...

MySQL中处理JSON数据:大数据分析的新方向,详解与示例

文章目录 1. MySQL中的JSON数据类型2. JSON函数和运算符3. 创建JSON列的表4. 插入JSON数据5. 查询JSON数据6. 复杂查询和聚合7. JSON 数据的索引8. 总结 在当今的大数据时代&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;作为一种轻量级的数据交换格式&a…...

【图形学】TA之路-矩阵

在 Unity 中&#xff0c;矩阵广泛用于处理各种图形变换&#xff0c;例如平移、旋转、缩放等。矩阵的使用不仅限于三维空间&#xff0c;还可以应用于二维空间的操作。了解矩阵及其运算对于游戏开发和计算机图形学非常重要。Unity 中使用的是行向量不是列向量&#xff0c;这个要注…...

LAMM: Label Alignment for Multi-Modal Prompt Learning

系列论文研读目录 文章目录 系列论文研读目录文章题目含义AbstractIntroductionRelated WorkVision Language ModelsPrompt Learning MethodologyPreliminaries of CLIPLabel AlignmentHierarchical Loss 分层损失Parameter Space 参数空间Feature Space 特征空间Logits Space …...

mac编译opencv 通用架构库的记录

1,通用架构 (x86_64;arm64&#xff09;要设置的配置项&#xff1a; CPU_BASELINE CPU_DISPATCH 上面这两个我设置成SSE_3&#xff0c;其他选项未尝试&#xff0c;比如不设置。 CMAKE_OSX_ARCHITECTURES:x86_64;arm64 WITH_IPP:不勾选 2,contrib库的添加&#xff1a; 第一次…...

Python 向IP地址发送字符串

Python 向IP地址发送字符串 在网络编程中&#xff0c;使得不同设备间能够进行数据传输是一项基本任务。Python提供了强大的库&#xff0c;帮助开发者轻松地实现这种通信。本文将介绍如何使用Python通过UDP协议向特定的IP地址发送字符串信息。 UDP协议简介 UDP&#xff08;用…...

上升响应式Web设计:纯HTML和CSS的实现技巧-1

响应式Web设计&#xff08;Responsive Web Design, RWD&#xff09;是一种旨在确保网站在不同设备和屏幕尺寸下都能良好运行的网页设计策略。通过纯HTML和CSS实现响应式设计&#xff0c;主要依赖于媒体查询&#xff08;Media Queries&#xff09;、灵活的布局、可伸缩的图片和字…...

利用java结合python实现gis在线绘图,主要技术java+python+matlab+idw+Kriging

主要技术javapythonmatlabidwKriging** GIS中的等值面和等高线绘图主要用于表达连续空间数据的分布情况&#xff0c;特别适用于需要展示三维空间中某个变量随位置变化的应用场景。 具体来说&#xff0c;以下是一些适合使用GIS等值面和等高线绘图的场景&#xff1a; 地形与地貌…...

Android全面解析之context机制(三): 从源码角度分析context创建流程(下)

前言 前面已经讲了什么是context以及从源码角度分析context创建流程&#xff08;上&#xff09;。限于篇幅把四大组件中的广播和内容提供器的context获取流程放在了这篇文章。广播和内容提供器并不是context家族里的一员&#xff0c;所以他们本身并不是context&#xff0c;因而…...

执行docker compose命令出现 Additional property include is not allowed

问题背景 在由docker-compose.yml的文件目录下执行命令 docker compose up -d 出现错误 Additional ininoperty include is not allowed 原因 我的docker-compose.yml 文件中出现了include标签旧版本的docker-compose 不支持此标签 解决办法 下载支持的docker-compose 解决…...

STM32通过I2C硬件读写MPU6050

目录 STM32通过I2C硬件读写MPU6050 1. STM32的I2C外设简介 2. STM32的I2C基本框图 3. STIM32硬件I2C主机发送流程 10位地址与7位地址的区别 7位主机发送的时序流程 7位主机接收的时序流程 4. STM32硬件与软件的波形对比 5. STM32配置硬件I2C外设流程 6. STM32的I2C.h…...

ubuntu2204-中文输入法-pycharm-python-django开发环境搭建

文章目录 1.系统常用设置1.1.安装中文输入法1.2.配置输入法1.3.卸载输入法1.4.配置镜像源2.java安装3.pycharm安装与启动4.卸载ubuntu2204默认版本5.安装Anaconda5.1.安装软件依赖包5.2.安装命令5.3.激活安装5.4.常用命令5.5.修改默认启动源6.安装mysql6.1.离线安装mysql6.2.在…...

【学习笔记】Matlab和python双语言的学习(一元线性回归)

文章目录 前言一、一元线性回归回归分析的一般步骤一元线性回归的基本形式回归方程参数的最小二乘法估计对回归方程的各种检验估计标准误差的计算回归直线的拟合优度判定系数显著性检验 二、示例三、代码实现----Matlab四、代码实现----python回归系数的置信区间公式残差的置信…...

LeetCode //C - 316. Remove Duplicate Letters

316. Remove Duplicate Letters Given a string s, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results. Example 1: Input: s “bcabc”…...

【ARM+Codesys 客户案例 】RK3568/A40i/STM32+CODESYS在工厂自动化中的应用:PCB板焊接机

现代化生产中&#xff0c;电子元件通常会使用自动化设备来进行生产&#xff0c;例如像PCB&#xff08;印刷电路板&#xff09;的组装。但是生产过程中也会面临一些问题&#xff0c;类似于如何解决在PCB板上牢固、精准地安装各种组件呢&#xff1f;IBL Lttechnik GmbH公司的CM80…...

【二分查找】--- 初阶题目赏析

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; 算法Joureny 上篇我们讲解了关于二分的朴素模板和边界模板&#xff0c;本篇博客我们试着运用这些模板。 &#x1f3e0; 搜索插入位置 &#x1f4cc; 题目…...

【PostgreSQL003】PostgreSQL数据表空间膨胀,磁盘爆满,应用宕机(经验总结,已更新)

1.一直以来想写下基于PostgreSQL的系列文章&#xff0c;作为较火的数据ETL工具&#xff0c;也是日常项目开发中常用的一款工具&#xff0c;最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下PostgreSQL数据库相关知识体系。空间膨胀&#xff08;主键、外键、…...

C语言第20天笔记

文件操作 概述 什么是 文件 文件时保存在外存储器上&#xff08;一般代指磁盘&#xff0c;也可以是U盘、移动硬盘等&#xff09;的数据的集合。 文件操作体现在哪几个方面 1. 文件内容的读取 2. 文件内容的写入 数据的读取和写入可被视为针对文件进行输入和输出的操作&a…...

为什么穷大方

为什么有些人明明很穷&#xff0c;却非常的大方呢&#xff1f; 因为他们认知太低&#xff0c;根本不懂钱的重要性&#xff0c;总是想着及时享乐&#xff0c;所以一年到头也存不了什么钱。等到家人孩子需要用钱的时候&#xff0c;什么也拿不出来&#xff0c;还到处去求人。 而真…...

HiveSQL实战——大数据开发面试高频SQL题

查询每个区域的男女用户数 0 问题描述 每个区域内男生、女生分别有多少个 1 数据准备 use wxthive; create table t1_stu_table (id int,name string,class string,sex string ); insert overwrite table t1_stu_table values(4,张文华,二区,男),(3,李思雨,一区,女),(1…...

RabbitMQ集群 - 普通集群搭建、宕机情况

文章目录 RabbitMQ 普通集群概述集群搭建数据准备启动容器宕机情况 RabbitMQ 普通集群 概述 1&#xff09;普通模式中所有节点没有主从之分&#xff0c;所有节点的元数据&#xff08;交换机、队列、绑定等&#xff09;都是一致的. 例如只要有任意一个节点上面 新增交换机&…...

xssDOM型练习

文章目录 例1要求 例2代码解析方法 例3例4例5例6例7例8 例1 本题通过get接收并传递参数&#xff0c;所有参数不经过过滤直接放入h2标签里面。 要求 1.需要页面弹出1337 2.不能与用户交互 官方认为innerHTML中script标签不安全&#xff0c;所以将其禁用&#xff0c;但只禁用了…...

python中的gradio使用麦克风时报错

python中的gradio使用麦克风时报错 当运行至 import gradio as gr with gr.Blocks() as demo:with gr.Tab("microphone transcriber"):gr.Audio(source"microphone", type"numpy", streamingTrue)demo.queue()##访问链接 https://ip:1235/demo…...

Oracle(63)什么是临时表(Temporary Table)?

临时表&#xff08;Temporary Table&#xff09;是一种特殊类型的表&#xff0c;用于存储临时数据&#xff0c;这些数据在会话期间或事务期间是短暂的。临时表在不同的数据库系统中都有实现&#xff0c;但功能和特性可能有所不同。临时表通常用于存储中间计算结果、临时数据处理…...

《Techporters架构搭建》-Day06 国际化

什么是国际化&#xff1f; 国际化&#xff0c;也叫i18n&#xff0c;为什么叫i18n呢&#xff1f; "i18n"是国际化&#xff08;internationalization&#xff09;的缩写&#xff0c;数字18代表了国际化这个单词中间的字母数量。类似这样的缩写还有k8s&#xff08;kube…...

Linux ACL 访问控制

今天给伙伴们分享一下Linux ACL 访问控制&#xff0c;希望看了有所收获。 我是公众号「想吃西红柿」「云原生运维实战派」作者&#xff0c;对云原生运维感兴趣&#xff0c;也保持时刻学习&#xff0c;后续会分享工作中用到的运维技术&#xff0c;在运维的路上得到支持和共同进步…...

hg transformers pipeline使用

什么是hg transformers pipeline? 在Hugging Face的transformers库中&#xff0c;pipeline是一个高级API&#xff0c;它提供了一种简便的方式来使用预训练模型进行各种NLP任务&#xff0c;比如情感分析、文本生成、翻译、问答等。通过pipeline&#xff0c;你可以在几行代码内…...

高性能内存对象缓存

Memcached概述 一套开源的高性能分布式内存对象缓存系统 所有的数据都存储在内存中 支持任意存储类型的数据 提高网站的访问速度 数据存储方式与数据过期方式 数据存储方式:Slab Allocation 按组分配内存&#xff0c;每次先分配一个Slab&#xff0c;相当于一个大小为1M的页&…...

文件上传-CMS文件上传分析

黑盒思路&#xff1a; 上传点抓包测试 个人用户中心是否存在文件上传功能后台管理系统是否存在文件上传功能字典目录扫描探针文件&#xff08;eg&#xff1a;upload.php&#xff09;构造地址字典目录扫描探针编辑器目录构造地址&#xff08;编辑器目录一般是默认的&#xff09…...

云原生日志Loki

1. Loki简介 1.1 Loki介绍 Loki是 Grafana Labs 团队最新的开源项目&#xff0c;是一个水平可扩展&#xff0c;高可用性&#xff0c;多租户的日志聚合系统。它的设计非常经济高效且易于操作&#xff0c;因为它不会为日志内容编制索引&#xff0c;而是为每个日志流编制一组标签…...

初阶数据结构之直接选择排序和快速排序

直接选择排序 1.在元素集合 array[i]–array[n-1] 中选择关键码最⼤(⼩)的数据元素 2.若它不是这组元素中的最后⼀个(第⼀个)元素&#xff0c;则将它与这组元素中的最后⼀个&#xff08;第⼀个&#xff09;元素 交换 3.在剩余的 array[i]–array[n-2]&#xff08;array[i1]–…...

Java语言程序设计——篇十三(4)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f333;&#x1f333;&…...

低代码: 组件库测试之渲染和元素获取,触发事件,更新表单,验证事件以及异步请求

组件库测试步骤 渲染组件(怎样将一个组件渲染到测试用例里面) mount 和 shallowMount传递属性元素是否成功的显示 查找元素的不同写法get, getAllfind, findAllfindComponent 和 getComponent触发事件(是click也好,是input也好,让它触发对应的事件) trigger 方法观察测试界面…...

银河麒麟服务器操作系统Kylin-Server-V10-SP3-2403-Release-20240426-x86_64安装步骤

银河麒麟服务器操作系统 Kylin-Server-V10-SP3-2403-Release-20240426-x86_64安装步骤 一、准备工作1. 下载ISO镜像2. 制作安装介质3. 设置BIOS 二、安装过程1. 启动系统2. 选择安装语言3. 选择安装配置4. 配置root密码与创建用户5. 开始安装6. 重启系统7. 同意许可协议 三、系…...

2024年电赛H题全开源

当题目出来的的那一刻&#xff0c;看到了M0芯片&#xff0c;我们实验室只有一块板子&#xff0c;并且我没有接触过M0&#xff0c;电赛只准备了TI的MSP430f5529。但是我并没有放弃&#xff0c;决然的选择了H题。基本上将四问全做出来&#xff0c;可是测试由于使用了感为科技的寻…...

Docker:宿主机可以ping通外网,docker容器内无法ping通外网之解决方法

问题描述 1、宿主机可以ping外网&#xff0c;docker容器内无法ping外网 ping www.baidu.com 提示&#xff1a;unknown host baidu.com 2、宿主机可以wget下载&#xff0c;docker容器内无法wget下载 wget www.baidu.com 提示&#xff1a;unknown host baidu.com 解决方法 1、…...

bootchart抓Android系统启动各阶段性能数据

最近在做Android系统启动优化&#xff0c;首要任务是找到启动过程中各阶段耗时点&#xff0c;进而有针对性地进行优化。主要用bootchart抓开机数据&#xff0c;本文主要记录下工具的使用方法。 1.抓开机数据 adb root adb shell ‘touch /data/bootchart/enabled’ adb rebo…...

使用 Node.js 和 Express 框架通过网页访问GPIO和嵌入式 Linux 系统中使用 GSM/3G/4G 模块

点击上方"蓝字"关注我们 01、前言 想要快速开发嵌入式 Linux 网络应用,控制硬件 GPIO,从而使得用户能够远程控制和监控系统。 主要目的是向读者展示开发使用文件系统控制 GPIO 的 Node 代码、创建用户有好的界面、以及运行基于 Express 框架使用 AJAX 通客户端进…...

IT 行业的就业情况

当前&#xff0c;IT 行业的就业情况呈现出以下特点&#xff1a; 1. 需求持续增长&#xff1a;随着数字化转型的加速&#xff0c;各个行业对信息技术的依赖程度不断提高&#xff0c;推动了对 IT 人才的持续需求。特别是在云计算、大数据、人工智能、物联网等新兴领域&#xff…...

如何快速获取麒麟操作系统版本信息

如何快速获取麒麟操作系统版本信息 一、桌面版系统1. 使用 /etc/kylin-build 文件2. 使用 /etc/.kyinfo 文件 二、服务器版系统1. 使用 /etc/.productinfo 文件2. 使用 nkvers 命令3. 使用 /etc/kylin-release 文件 三、总结 &#x1f496;The Begin&#x1f496;点点关注&…...

git提交规范检查husky

一、Eslint 尤雨溪推荐的 prettierrc 配置&#xff0c;句尾不带分号 单引号。 尤雨溪推荐配置&#xff1a;vue-next/.prettierrc lint lint 是最著名的 C 语言工具之一&#xff0c;是由贝尔实验室 SteveJohnson 于 1979 在 PCC(PortableC Compiler) 基础上开发的静态代码分…...

LeetCode 919. 完全二叉树插入器

完全二叉树是每一层&#xff08;除最后一层外&#xff09;都是完全填充&#xff08;即&#xff0c;节点数达到最大&#xff09;的&#xff0c;并且所有的节点都尽可能地集中在左侧。 设计一个用完全二叉树初始化的数据结构 CBTInserter&#xff0c;它支持以下几种操作&#xf…...

C++密码管理器

先问一句 最近有几个关注我的原力等级为0或-1&#xff0c;文章全是转载&#xff0c;转载时间基本都在2021年&#xff0c;而且关注了很多人&#xff0c;这些是僵尸粉吗&#xff1f; 文末有投票&#xff0c;麻烦参与一下谢谢 实现功能列表 暂时还没做加密功能 打算用openssl/a…...

算法【Java】 —— 滑动窗口

滑动窗口 在上一篇文章中&#xff0c;我们了解到了双指针算法&#xff0c;在双指针算法中我们知道了前后指针法&#xff0c;这篇文章就要提到前后指针法的一个经典的使用 —— 滑动窗口&#xff0c;在前后指针法中&#xff0c;我们知道一个指针在前&#xff0c;一个指针在后&a…...