sscanf, sprintf, sscanf_s
sscanf和sprintf是非常好用的类型转换工具,用于char[]类型字符数组和int, float, double 等基本数据类型进行转换,然后进行相应操作。很是方便,另外对于字符串,想转int还有atoi函数,想转double还有atof函数。下一篇文章再介绍。
1.基本用法 —— str[ ] 与 int float double 的转换
#include <iostream>
#include<cstdio>
#include<string>
using namespace std;
#include<string.h>
#include<stdio.h>
#include<iomanip>
int main()
{
//用于测试的变量
int a1 = 1;
float a2 = 2.3;
double a3 = 3.3;
// sscanf sprintf
//函数原型
//sscanf(char[], "%d", &int); 将char[]中的内容以%d的形式写入int型变量
//sprintf(char[], "%d", int);
//函数的第一个参数是字符数组,这个是固定的,下面测试一下
//1.测试int
// char str[] = "1234";
// sscanf(str, "%d", &a1);
// cout<<"测试1:"<<a1<<endl;
//2.测试float
// char str[] = "123.444";
// sscanf(str, "%f", &a2);
// cout<<"测试float:"<<a2<<endl;
//3.测试double
// char str[] = "22.3333333333";//10个3
// sscanf(str, "%lf", &a3); //这里注意 double 写入的时候的格式是%lf,输出是%f
// cout<<std::setprecision(12)<<endl;
// cout<<"测试a3:"<<a3<<endl;
//4.测试char[]
// char str[] = "Lumen";
// char str2[100];
// sscanf(str, "%s", str2);
// cout<<"测试str2:"<<str2<<endl;
//5.一起测试
//5.1 错误的测试 会发现score写不进去,因为分隔符逗号被当作字符串的一部分被写入了
// char str[] = "20132222,刘和刚,99.222";
// int id;
// char name[100];
// double score;
// sscanf(str, "%d,%s,%lf", &id, name, &score);
// cout<<"一起测试:"<<endl;
// cout<<id<<endl;
// cout<<name<<endl;
// cout<<score<<endl;
//5.2 所以最好是把需要被写入的char[] 放在最后读入,这样就没问题了
// char str[] = "20132222,99.222,刘和刚";
// int id;
// char name[100];
// double score;
// sscanf(str, "%d,%lf,%s", &id, &score, name);
// cout<<"一起测试:"<<endl;
// cout<<id<<endl;
// cout<<name<<endl;
// cout<<score<<endl;
//6.sprintf一样的,也测试一下
// char str[100]; //用于将各种数据写入
// int b1 = 100;
// float b2 = 1.5;
// double b3 = 2.6666666666;
// char str2[] = "刘和刚";
// sprintf(str, "%d, %f, %f, %s!", b1,b2,b3,str2);
// cout<<setprecision(12);
// cout<<"测试sprintf:"<<endl;
// cout<<str<<endl;
//6.sprintf将%s放在中间 ,也是可以的
// char str[100]; //用于将各种数据写入
// int b1 = 100;
// float b2 = 1.5;
// double b3 = 2.6666666666;
// char str2[] = "刘和刚";
// sprintf(str, "%d, %s,%f, %f!", b1, str2, b2,b3);
// cout<<setprecision(12);
// cout<<"测试sprintf:"<<endl;
// cout<<str<<endl;
//7.sscanf和sprintf的第一个参数除了char str[] 字符数组名(即一个char*)之外,还可以是什么
//7.1 测试看看string
// string s1 = "";
// int c1 = 19;
// float c2 = 1.2;
// double c3 = 2.333333;
// sprintf(s1, "%d %f %f", c1, c2, c3);
// cout<<"测试第一个参数能否是string:"<<endl;
// cout<<s1<<endl;
//编译不通过,不可行
return 0;
}
2.常见用法—— 指定长度 正则表达式
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB’] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,并且停止读入,贪婪性
- 返回值问题
成功则返回参数数目,失败则返回-1
sscanf(“1 2 3”,"%d %d %d",buf1, buf2, buf3); 成功调用返回值为3,即buf1,buf2,buf3均成功转换。
sscanf(“1 2”,"%d %d %d",buf1, buf2, buf3); 成功调用返回值为2,即只有buf1,buf2成功转换。
- sscanf 跳过某些中间内容("%*数据类型"表达式)
char str_[] = "1.5,4.444,刘和刚";
char recevie[100];
double rec;
int num = sscanf(str_, "%*lf,%lf,%s", &rec, recevie); //num是成功转换的次数
cout<<rec<<endl;
cout<<recevie<<endl;
cout<<num<<endl;//返回了2
//又或者是将带空格的字符串中空格之前的内容去掉
//char buf[100];
//sscanf("hello, world", "%*s%s", buf);
//cout<<buf<<endl;
- 取指定长度的字符串
sscanf("123456","%4s",buf);
printf("%s\n",buf);
- 读取到指定字符串为止("%[^ ]"表达式)
char buf[100];
sscanf("12345aas2222", "%[^a-z]", buf); //遇到小写字母即止
cout<<buf<<endl;
5.读取指定好的类型字符("%[ ]"表达式)
char buf[100];
sscanf("12345aasSSSS22sd23222***", "%[1-9a-zA-Z]", buf);//仅读取字母和数字,遇到*就停止
cout<<buf<<endl;
- 读取某两个字符之间的内容
char buf[100];
sscanf("linows@18842222333*balabala...", "%*[^@]@%[^*]", buf);
//先过滤掉%* 非@[^@] 的内容,跟进一个@不读入,然后读进% 所有不是*的内容[^*],遇到*即止
cout<<buf<<endl;
- 以TAB间隔的数据读取
char buf1[100];
char buf2[100];
char buf3[100];
sscanf("a bb ccc", "%s\t%s\t%s", buf1, buf2, buf3);
cout<<buf1<<"\t"<<buf2<<"\t"<<buf3<<endl;
3.sscanf_s
sscanf_s()函数比sscanf考虑了更多安全性问题,但实际调用方法类似,不再赘述,见参考文档。