经常遇到文件、控制台和字符串为缓冲区的格式化输入输出,所以很有必要总结一下,争取毕其功于一役,以后遇到此类问题不再到处查阅。
C语言中的几种输入方式:
scanf() 从控制台键盘输入;
sscanf() 从字符串缓冲区输入与指定格式相符的数据;
fscanf() 从文件输入;
平时使用中遇到的最大问题就是这几个函数的参数弄不明白彻底;其实想搞明白这一点需要了解一下正则表达式。
这里有篇正则表达式的教程可以参考一下:http://www.runoob.com/regexp/regexp-tutorial.html。
http://www.cplusplus.com/reference/上找到三个函数的函数原型:
int scanf ( const char * format, ... );
int sscanf ( const char * s, const char * format, ...);
int fscanf ( FILE * stream, const char * format, ... );
三个函数有相同的参数const char * format;
1、 * 亦可用于格式中, (即 %*d 和 %*s) 加了星号 (*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)
%*d:匹配到的整数被过滤掉
%*s:匹配到的字符串被过滤掉
%*[a] :匹配到的a字符均被过滤掉
2、{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。(没明白怎么用,可以给讲讲)
3、width表示读取宽度。
%6c :读取匹配到的6个字符
4、{h | l | I64 | L}:参数的size,通常h表示单字节size,I表示2字节 size,L表示4字节size(double例外),l64表示8字节size。 (没明白怎么用,可以给讲讲)
5、type :这就很多了,就是%s,%d之类。
6、特别的:%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值失败返回0 ,否则返回格式化的参数个数
%*8c :过滤掉匹配到的8个字符
7、如果读取的字符串,不是以空格来分隔的话,就可以使用%[]。
经常读取的字符串中有分隔符可以使用 %*[分隔符] 将分隔符过滤掉。
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配),
%[^a-z] 读取不在a-z之间的字符串。如果碰到a-z之间的字符串则停止
%[aB'] 匹配a、B、'三者中一员,贪婪性
%[^a] 匹配非a的任意字符,一旦遇到a停止读入,贪婪性。其中‘^’后面可以带更多的字符。
综上,%[ ] 表示要读入一个字符集合如果'['后面第一个字符是“^”,则表示相反的意思,[ ]内的字符为1个或者更多字符组成的,各个字符之间是并列关系。
#include
#include
#include
using namespace std;
#define BUFSIZE 128
int main()
{
//注意:什么位置的空格才可以被自动略过
double x = 0.0, y = 0.0, z=0.0;
char * text1 = "ENU:37.69129, 110.97952 ,2583.369";
int num = sscanf(text1, "%*[A-Z]%*[:]%lf,%lf%*[ ],%lf", &x, &y, &z);
printf("x:%lf, y:%lf, z:%lf\n", x, y, z); //x:37.691290, y:110.979520, z:2583.369000
x = 0.0, y = 0.0, z = 0.0;
num = sscanf(text1, "%*4c%lf,%lf%*[ ],%lf", &x, &y, &z);
printf("x:%lf, y:%lf, z:%lf\n", x, y, z); //x:37.691290, y:110.979520, z:2583.369000
char * des = (char*)malloc(BUFSIZE);
char * des0 = (char*)malloc(BUFSIZE);
char buffer[BUFSIZE] = " 38.259 , 5896 DEVOTIOON";
char buf[BUFSIZE] = "38.259 , 5896 stay foolish";
//1.一般用法
sscanf(buffer, "%s", des);
printf("%s \n", des);
//2.取指定长度的字符串,取最大长度为4的字符串
memset(des, '\0', BUFSIZE);
sscanf(buffer, "%4s", des);
printf("%s \n", des); //38.2
//3.取到指定字符为止的字符串, 如取遇到空格为止的字符串
memset(des, '\0', BUFSIZE);
sscanf(buf, "%[^ ]",des);
printf("%s \n", des); //38.259
//4.取仅包含指定字符集的字符串: 取包含1-9和小写字母的字符串
memset(des, '\0', BUFSIZE);
sscanf(buffer, "%[1-9 ,.]",des); //"%[1-9 ,.]"含有空格
printf("%s \n", des); // 38.259 , 5896
//取到指定字符集为止的字符串。 取遇到大写字母为止的字符串
memset(des, '\0', BUFSIZE);
sscanf(buffer, "%[^A-Z]", des);
printf("%s \n", des); // 38.259 , 5896
//给定一个字符串itertor/54367#,获取 / 和 # 之间的字符串,
//%*[^/]过滤掉非'/'的字符,'/'字符存在,%[^#]读取非'#'的字符,遇到'#'停止,将读取的非"#"字符传到des
memset(des, '\0', BUFSIZE);
sscanf("itertor/54367#", "%*[^/]/%[^#]", des);
printf("%s\n", des); //54367
//scanf() 的两个小例子
//输入一个字符串,这个祖父穿只含有小写字符,遇到第一个不是小写字符时停止
char * str = (char*)malloc(BUFSIZE);
printf("Please input lowercase characters:");
scanf("%[a-z]", str);
printf("received lowercase characters%s \n", str);
////输入一个字符串,遇到字符"."停止。
memset(str, '\0', BUFSIZE);
printf("Please input lowercase string(quit with signal ';' ouccrring):");
scanf("%[^;]", str);
printf("received lowercase characters%s \n", str);
free(des);
free(des0);
return 0;
}
https://blog.csdn.net/21aspnet/article/details/174326 这篇博文讲解的scanf很详细,见过最好的。
https://www.cnblogs.com/mylinux/p/4635510.html
参考: https://www.jb51.net/article/138506.htm
http://www.runoob.com/regexp/regexp-tutorial.html
scanf()常犯错误 (讲解scanf非常详细)