一、scanf("%[^\n]", str)正则用法
1 ^
表示"非",[^\n]
表示读入换行字符就结束读入。这个是scanf的正则用法,我们都知道scanf不能接收空格符,一接受到空格就结束读入,所以不能像gets()等函数一样接受一行字符串,但是使用%[^\n]
就可以读取一行,直到碰到’\n’才结束读入。
2 *
表示该输入项读入后不赋予任何变量,即scanf("%*[^\n]%*c")
表示跳过一行字符串。其中%c可以把’\n’吸收掉,防止影响后续输入。
#include<iostream>
using namespace std;
int main()
{
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("%*[^\n]");因为不会存储任何字符
scanf("%*[^#]", str4); // 过程4 加了个*,本句功能相当于scanf("%*[^#]");因为不会存储任何字符
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’还在缓冲区,只要scanf正则表达式合适,完全可以被后续输入得到。
过程2:读到Are you sure?\n# 末尾的 ‘#’ 时,结束。像上面一样 ‘#’ 也还在缓冲区,加上之前过程1留在缓冲区的’\n’在前,str2字符串为"\nAre you sure?\n"
过程3:读到"Are you ok?“的末尾’\n’时,结束,但是并不存储"Are you ok?”,相当于跳过一行,这跳过的所谓的“一行”也包括过程2留在缓冲区的’#’。而末尾的’\n’留在缓冲区。
过程4:读入两行,读到"No, I can’t. "后面的’#’,才结束,当然’#'还在缓冲区,之前的全部跳过不存储。
最后输出的时候,只有str1和str2真正输出了,str3,str4本身就没有存储任何字符,自然也就无输出。
注意:有人喜欢写scanf("%[^\n]%*c", str),目的是可以把’\n’吸收掉(即读取但不存储),防止影响后续输入
特意查了下scanf(),getchar(),getche(),getch()这些函数缓冲区角度的解释:
写的真的好,解决了我一年的懵懵懂懂:
https://www.cnblogs.com/yhjoker/p/7530837.html
二、strchr用法
这是C的库函数
原型:char *strchr(const char *str, int c)
作用:在参数 str 所指向的字符串中搜索第一次出现字符 c(一个无符号字符)的位置。
下面是示例代码:
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char str[] = "I love you.cn";
char ch = '.';
char *point;
point = strchr(str, ch);
printf("|%c| 之后的字符串是 - |%s|\n", ch, point);
}
输出结果:
|.| 之后的字符串是 - |.cn|
有人不清楚为啥输出的是 ‘.’ 后面的字符串,请想想printf("%s", str)的原理。
另外,如果没有找到ch这个字符的话(例子里面是’.’),就返回NULL。