开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
scanf() : C 库函数 int scanf (const char *format, ...) 从 stdin 读取格式化的输入。
Syntax: int scanf(const char *format, ...) Return type: Integer Parameters: format: 包含类型说明符的字符串 "..." (ellipsis): 指示函数接受可变数量的参数 复制代码
每个参数必须是写入转换结果的内存地址。成功后,该函数返回填充的变量数。如果输入失败,在成功读取任何数据之前,将返回 EOF。
可在 scanf 中使用的类型说明符:
%c — Character %d — Signed integer %f — Floating point %s — String 复制代码
//C 程序演示scanf语句 #include <stdio.h> #include <stdlib.h> int main() { char a[10]; printf("Please enter your name : \n"); //scanf语句 scanf("%s", a); printf("You entered: \n%s", a); return 0; } 复制代码
输入:
haiyong 复制代码
输出:
Please enter your name : You entered: haiyong 复制代码
sscanf( ):sscanf( ) 用于从字符串中读取格式化的输入。
Syntax: int sscanf ( const char * s, const char * format, ...); Return type: Integer Parameters: s: 用于检索数据的字符串 format: 包含类型说明符的字符串 … : 参数包含用于分配具有适当类型的存储的指针。 这些参数的数量应至少与格式说明符存储的值的数量相同。 复制代码
成功后,该函数返回填充的变量数。在输入失败的情况下,在成功读取任何数据之前,将返回 EOF。
// 说明sscanf语句的C程序 #include <stdio.h> int main () { // 声明数组 s char s [] = "3 red balls 2 blue balls"; char str [10],str2 [10]; int i; // %*s用于跳过单词 sscanf (s,"%d %*s %*s %*s %s %s", &i, str, str2); printf ("%d %s %s \n", i, str, str2); return 0; } 复制代码
输出:
3 blue balls 复制代码
fscanf( ):fscanf( ) 从文件中读取格式化数据并将其存储到变量中。
Syntax: int fscanf(FILE *stream, const char *format, ...) Parameters: Stream: 指向标识流的File对象的指针。 format: 是包含类型说明符的字符串 复制代码
成功后,该函数返回填充的变量数。在输入失败的情况下,在成功读取任何数据之前,将返回 EOF。
// 说明sscanf语句的C程序 //此程序将在文件file.txt的系统上运行 #include <stdio.h> #include <stdlib.h> int main() { char s1[10], s2[10], s3[10]; int year; // 文件指针 FILE * fp; // 打开/创建文件 fp = fopen ("file.txt", "w+"); // 在文件中存储字符串 fputs("Hello World its 2017", fp); // 将文件位置设置为文件的开头 rewind(fp); // 从文件中获取输入 fscanf(fp, "%s %s %s %d", s1, s2, s3, &year); printf("String1 |%s|\n", s1 ); printf("String2 |%s|\n", s2 ); printf("String3 |%s|\n", s3 ); printf("Integer |%d|\n", year ); // 关闭文件指针 fclose(fp); return(0); } 复制代码
输出:
String1 |Hello| String2 |World| String3 |its| Integer |2017| 复制代码
scanf_s() : 此函数特定于微软编译器。它与 scanf 相同,只是不会导致缓冲区过载。
Syntax: int scanf_s(const char *format [argument]...); argument(parameter): 在这里,您可以指定缓冲区大小并实际控制输入应用程序的限制。 复制代码
成功后,该函数返回填充的变量数。在输入失败的情况下,在成功读取任何数据之前,将返回 EOF。
为什么要使用 scanf_s()?
scanf 只读取控制台提供的任何输入。C 不检查用户输入是否适合您指定的变量。
如果你有一个名为 color[3] 的数组,并且你使用 scanf 表示 “Red”,它会正常工作,但如果用户输入超过 3 个字符,scanf 开始写入不属于 color 的内存。C 不会捕获或警告您,它可能会也可能不会使程序崩溃,具体取决于是否有内容试图访问并写入不属于颜色的内存插槽。这就是scanf_s发挥作用的地方。scanf_s检查用户输入是否适合给定的内存空间。
// 说明sscanf_s语句的C程序 //scanf_s()只能在Microsoft Visual Studio中工作。 #include <stdio.h> #include <stdlib.h> int main() { char a[5]; // sizeof(a)是缓冲区大小 scanf_s("%s", a, sizeof(a)); printf("\n%s ", a); return 0; } 复制代码
输入:
Red 复制代码
输出:
Red 复制代码
输入:
Yellow 复制代码
输出:
No Output 复制代码
说明缓冲区大小和数组大小之间的关系。
// C程序使用输入后按下的Enter键(换行符) #include<stdio.h> char ch[100000]; printf("Enter characters: "); scanf_s("%s", ch, 99999); getchar(); 复制代码
// C++程序使用输入后按下的Enter键(换行符) #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { // 实例 char ch[100000]; printf("Enter characters: "); scanf_s("%s", ch, 99999); getchar(); return 0; } 复制代码
- 如果缓冲区大小等于或小于数组的大小,则输入大于或等于缓冲区大小将不执行任何操作。
- 如果缓冲区大小大于数组的大小,则
- a. 输入小于缓冲区大小将起作用,但会给出错误
“运行时检查失败 #2 – 变量'variable_name'周围的堆栈已损坏。” 复制代码
- b. 输入大于缓冲区大小将无助于任何操作并给出相同的错误。
fscanf_s() : fscanf() 和 fscanf_s() 之间的区别与 scanf() 和 scanf_s() 的区别相同。fscanf_s() 是安全函数,安全函数要求每个 c、C、s、S 和 [ type 字段的大小作为紧跟变量后面的参数传递。
Syntax: int fscanf_s( FILE *stream, const char *format ,[argument ]... ); fscanf_s has an extra argument(parameter) where you can specify the buffer size and actually control the limit of the input. 复制代码
成功后,该函数返回填充的变量数。在输入失败的情况下,在成功读取任何数据之前,将返回 EOF。
// 说明fscanf_s语句的C程序此程序将在MS Visual studio上运行 #include <stdio.h> #include <stdlib.h> int main() { char s1[10], s2[10], s3[10]; int year; // 文件指针 FILE * fp; // 安全打开文件 fopen_s(&fp,"file.txt", "w+"); fputs("Hello World its 2017", fp); rewind(fp); // 使用 fscanf_s fscanf_s(fp, "%s", s1, sizeof(s1)); fscanf_s(fp, "%s", s2, sizeof(s2)); fscanf_s(fp, "%s", s3, sizeof(s3)); fscanf_s(fp, "%d", &year, sizeof(year)); printf("String1 |%s|\n", s1); printf("String2 |%s|\n", s2); printf("String3 |%s|\n", s3); printf("Integer |%d|\n", year); fclose(fp); return(0); } 复制代码
输出:
String1 |Hello| String2 |World| String3 |its| Integer |2017| 复制代码
sscanf_s() : sscanf_s() 是 sscanf() 的安全函数,安全函数要求每个 c、C、s、S 和 [ 类型字段的大小作为紧跟在变量后面的参数传递。
Syntax: int sscanf_s(const char *restrict buffer, const char *restrict format, ...); sscanfs有一个额外的参数(参数),您可以在其中指定缓冲区大小并实际控制输入的限制。 复制代码
成功后,该函数返回填充的变量数。在输入失败的情况下,在成功读取任何数据之前,将
返回 EOF。
//说明sscanf_s语句的C程序 //此程序将在MS Visual studio上运行 #include <stdio.h> int main() { char s[] = "3 red balls 2 blue balls"; char str[10], str2[10]; int i; // %*s用于跳过单词 sscanf_s(s, "%d", &i, sizeof(i)); sscanf_s(s, "%*d %*s %*s %*s %s", str, sizeof(str)); sscanf_s(s, "%*d %*s %*s %*s %*s %s", str2, sizeof(str2)); printf("%d %s %s \n", i, str, str2); return 0; } 复制代码
输出:
3 blue balls 复制代码
注意: sscanf_s() 仅适用于 Microsoft Visual Studio。