scanf(“%[^n],c)和scanf(“%[^ ],c)具体含义

本文深入解析C语言中scanf函数的使用方法,特别是%[^]和%[^ ]格式控制符的区别,以及如何处理字符串读取直到特定字符或换行符。通过实例演示了不同场景下的应用,帮助读者理解如何有效控制输入。

【扩展知识1】scanf("%[^n],c)和scanf("%[^ ],c)具体含义

     以前自己也遇到这些问题,也查了查,但慢慢的又忘了~- ~。今天又碰到,所以就把它写成篇文章吧,以供大家查阅。本文中写的内容有参考网上高手们的,我只是总结总结,谢谢。   

#include <stdio.h>
int main( void )
{

	char array[ 100 ];

	printf("输入要打印的内容: " );

	scanf( "%s", array );  

	printf( "您输入的内容为: %s\n", array );

	return 0;

}

解读:第一个程序使用的scanf(“%[^ ]”, array)是读入字符串直到遇到空格结束。第二个程序使用的是scanf(“%s”, array);也是遇到空格就结束。

比如输入:abcdefg abcdefg abcdefg

输出结果:abcdefg

#include <stdio.h>
int main( void )
{

         chararray[ 100 ];

         printf("输入要打印的内容:" );

         scanf("%[^\n]", array ); 

         printf("您输入的内容为: %s\n", array );

         return0;
}

解读:本程序读取字符直到遇到’\n’或回车为止。
比如输入:abcdefg abcdefg abcedef
输出结果:abcdefg abcdefg abcedef
PS:输出字符串中有\n不是换行符,只能作为字符串中的一部分处理。
比如输入:abcdefg\n abcdefg abcdefg
输出结果:abcdefg\n abcdefg abcdefg

还有一种在前面加一个*的,scanf("%*[\n]")表示该输入项读入后不赋予任何变量,即scanf("%*[^\n]")表示跳过一行字符串。

#include<iostream>
using namespace std;
{
	char str1[1000] = {0};
	char str2[1000] = {0};
	char str3[1000] = {0};
	char str4[1000] = {0};
	scanf("%[^\n]", str1);    // 过程1
	scanf("%[^#]", str2);     // 过程2
	scanf("%*[^\n]", str3);   // 过程3 加了个*
	scanf("%*[^#]", str4);    // 过程4 加了个*
	cout << str1 << str2 << str3 << str4 << endl;
}  


输入

You are my friend
Are you sure?\n# 
Are you ok?
Can you speak English?
No, I can't. #

输出

you are my friend
Are you sure?\n

过程1:读到You are my friend(回车)末尾的’\n’时,结束,str1字符串为"You are my friend",
注意: '\n’确实也还在缓冲区,不过后续都是直接从缓冲区读取字符串而不是读取字符,所以会直接跳过(tab, 空格, ‘\n’)这类空白字符。
过程2:读到Are you sure?\n# 末尾的 ‘#’ 时,结束,像上面一样 ‘\n’ 也还在缓冲区,str2字符串为"Are you sure?\n"
过程3:读入字符串一直到"Are you ok?"的末尾’\n’,但是并不存储这个字符串,也不存储’\n’
过程4:读入两行,合整为字符串"Can you speak English?‘No, I can’t. "读到后面的’#’,结束,当然也是不存储’#’
注意:有人喜欢写scanf("%[^\n]%*c", str),目的是可以把’\n’吸收掉,防止影响后续输入

特意查了下scanf(),getchar(),getche(),getch()这些函数缓冲区角度的解释:
写的真的好,解决了我一年的懵懵懂懂:
https://www.cnblogs.com/yhjoker/p/7530837.html


总结:
综合上述,我们可以知道%[^\n]和%[^ ]的含义了。符号^ 表示取反的意思。[^ ]表示除了空格,所有的字符都可以读取;[^\n]则表示除了换行符,所有的字符都可以读取。
有时候,在程序中需要读取字符串直到回车为止,也可以使用函数gets(array)读取。


转载于http://oursharingclub.joinbbs.net和 codingit.howbbs.comA 

# 题目重述 使用 `scanf("%[^\n]")` 格式化字符串进行输入读取的问题。 # 详解 `scanf("%[^\n]")` 是 C 语言中 `scanf` 函数的一个格式化输入方式,用于读取**一行文本(不含换行符)**。其核心原理如下: - `%[^\n]` 是一种 scanset(扫描集)格式: - 方括号 `[ ]` 表示要匹配一组字符; - `^` 表示取反; - `\n` 表示换行符; - 所以 `%[^\n]` 的含义是:**读取所有不是换行符的字符**,直到遇到换行符为止。 因此,`scanf("%[^\n]", str)` 会将标准输入中当前行的所有字符(除了换行符)存入字符数组 `str` 中。 ### 示例代码 ```c #include <stdio.h> int main() { char str[100]; printf("请输入一行文字:\n"); scanf("%[^\n]", str); // 读取整行,不包括换行符 printf("你输入的是:%s\n", str); return 0; } ``` ### 注意事项 1. **不会自动消费换行符** `scanf("%[^\n]")` 只读取到换行前的内容,但换行符仍留在输入缓冲区中,下次输入可能会受到影响。通常需要用 `getchar()` 手动吸收它: ```c scanf("%[^\n]", str); getchar(); // 吸收换行符 ``` 2. **不检测缓冲区溢出** 如果输入长度超过数组容量,会导致缓冲区溢出,存在安全隐患。应指定最大宽度: ```c scanf("%99[^\n]", str); // 最多读取99个字符,留一个给'\0' ``` 3. **返回值检查** 应检查 `scanf` 的返回值以判断是否成功读取: ```c if (scanf("%99[^\n]", str) != 1) { printf("输入错误或为空!\n"); } ``` 4. **与 `gets` `fgets` 的比较** - `gets` 已废弃(不安全); - `fgets(str, size, stdin)` 更推荐,因为它自动包含换行符并防止溢出。 # 知识点(列出解答该问题需要的知识点) - **scanf格式化输入机制**:理解`%[^\n]`属于scanset规则,能自定义字符集合进行读取。 - **输入缓冲区管理**:掌握换行符残留问题及`getchar()`清除技巧。 - **字符串安全性处理**:通过限定输入宽度避免缓冲区溢出,提升程序健壮性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值