sscanf用法与snprintf用法

char str[100] = {0,}
一个字符是0,在C语言中,字符是ASCII码来存储的,一个字符一个字节,字符'\0'的ASCII码对应的是整型0
字符'\0'是一个不可以显示的字符,另一种说法就是,'\0'这个字符表示的NULL(空字符)
{0,}; 表示:给str这个字符数组的第一个字符赋值为NULL,而后面的其他字符都默认为NULL了。

1. sscanf用法

【作用】:从一个字符串中读进与指定格式相符的数据

【函数原型】:

  int sscanf( string str, string fmt, mixed var1, mixed var2 ... );
  int scanf( const char *format [,argument]... );

//sscanf与scanf类似,都是用于输入的,scanf以屏幕(stdin)为输入源,sscanf以固定字符串为输入源。

其中fmt为获取数据的格式,例如%d, %g(用来输出实数,它根据数值的大小,自动选f格式或e格式(选择输出时占宽度较小的一种),且不输出无意义的0), 支持集合操作:
%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)
%[aB'] 匹配a、B、'中一员,贪婪性
%[^a] 匹配非a的任意字符,贪婪性

注意:在读入的字符串是空字符串时,sscanf函数并不改变待读入到的变量的值。

【例子1】:将string转为int

int m = 5;
sscanf("123456 ", "%d", &m);
printf("%d\n", m);
//输出结果:123456

【例子2】:将中间有逗号分隔的string转化成多个int/实数

int x, y = -1;
float w, h = -1.0;

int m = 5;
sscanf("1,2,3.0,4.0", "%d,%d,%g,%g", &x, &y, &w, &h);
printf("x:[%d], y:[%d], w:[%g], h:[%g]\n", x, y, w, h);
// 输出结果是x:[1], y:[2], w:[3], h:[4]

【例子3】:

struct Color
{
	int alpha;  //如果这里是float,后面该怎么写?
	int red;
	int green;
	int blue;
};

Color normal;
Color press;

sscanf("{FF0000FF}, {FF00FFFF}", "{%02X%02X%02X%02X}, {%02X%02X%02X%02X}",
	&normal.alpha, &normal.red, &normal.green, &normal.blue,
	&press.alpha, &press.red, &press.green, &press.blue);
printf("normal.alpha:[%d], normal.red:[%d], normal.green:[%d], normal.blue:[%d]\n", normal.alpha, normal.red, normal.green, normal.blue);
printf("press.alpha:[%d], press.red:[%d], press.green:[%d], press.blue:[%d]\n", press.alpha, press.red, press.green, press.blue);
/* 输出结果是:
normal.alpha:[255], normal.red:[0], normal.green:[0], normal.blue:[255]
press.alpha:[255], press.red:[0], press.green:[255], press.blue:[255]
*/

参考
https://www.cnblogs.com/lyq105/archive/2009/11/28/1612677.html

2. snprintf用法

sprintf不能检查目标字符串的长度,可能造成众多安全问题,所以都会推荐使用snprintf

【函数原型】:

int snprintf(char*str, size_t size, const char*format, ...);
参数str:目标字符串
参数size:拷贝字节数(Bytes)
参数format:格式化成字符串
参数…: 可变参数

返回值:
1. 如果格式化后的字符串长度小于等于 size,则会把字符串全部复制到 str 中,并给其后添加一个字符串结束符 \0;
2. 如果格式化后的字符串长度大于 size,超过 size 的部分会被截断,只将其中的 (size-1) 个字符复制到 str 中,并给其后添加一个字符串结束符 \0,返回值为欲写入的字符串长度。

【例子1】:

char buffer[50];
int m = 1001001;

// 读取字符串并存储在 buffer 中
int j = snprintf(buffer, 6, "%d\n", m);

// 输出 buffer及字符数
printf("buffer:%s\ncount = %d\n", buffer, j);
/ *结果是
buffer:10010
count = 8   返回值?
*/

【例子2】:

int x = 1;
int y = 2;
float w = 3.0;
float h = 4.5;

char buff[50] = {0};

snprintf(buff, sizeof(buff), "%d,%d,%g,%g", x,y,w,h);
printf("buff:%s\n", buff);

//输出结果:buff:1,2,3,4.5

【例子3】:

struct Color
{
	int alpha;
	int red;
	int green;
	int blue;
};

struct ColorGroup
{
	Color normal;
	Color press;
};

ColorGroup colorGroup;
colorGroup.normal.alpha = 255;
colorGroup.normal.red = 255;
colorGroup.normal.green = 0;
colorGroup.normal.blue = 0;

colorGroup.press.alpha = 255;
colorGroup.press.red = 255;
colorGroup.press.green = 0;
colorGroup.press.blue = 255;


char buff[50] = {0};

snprintf(buff, sizeof(buff), "{%02X%02X%02X%02X}, {%02X%02X%02X%02X}",
	colorGroup.normal.alpha,colorGroup.normal.red,colorGroup.normal.green,colorGroup.normal.blue,
	colorGroup.press.alpha,colorGroup.press.red,colorGroup.press.green,colorGroup.press.blue);
printf("buff:%s\n", buff);

//输出结果:buff:{FFFF0000}, {FFFF00FF}

【总结】:
sscanf和sprintf占用大量的代码空间
如果字符串很复杂,使用正则表达式

posted on 2020-04-14 15:13  JJ_S  阅读(920)  评论(0编辑  收藏  举报