sscanf,sscanf_s及其相关用法
- 格式:doc
- 大小:60.00 KB
- 文档页数:7
sscanf函数的用法1. 函数定义sscanf函数是Matlab中的一个字符串处理函数,用于从字符串中按照指定格式读取数据。
它的基本语法为:A = sscanf(str, format);其中,str表示输入的字符串,format表示数据的格式。
该函数返回一个数组A,其中包含了从字符串中读取出来的数据。
2. 函数用途sscanf函数主要用于将字符串转换为数值型数据,并且可以根据需要指定不同的格式进行转换。
它在实际应用中有以下几个常见的用途:2.1 字符串解析sscanf函数可以方便地从一个复杂的字符串中提取出特定格式的数据。
比如,假设有一个字符串str = 'x=1, y=2, z=3',我们可以使用sscanf来解析该字符串,提取出其中x、y、z对应的数值。
代码如下:str = 'x=1, y=2, z=3';[A, count] = sscanf(str, 'x=%d, y=%d, z=%d');这样就可以得到变量A为一个包含了x、y、z三个数值的数组。
2.2 数据转换sscanf函数还可以将一些特定格式的字符串转换为其他类型的数据。
比如,将十六进制表示的字符转换为十进制整数或浮点数。
代码如下:str = '0xFF';A = sscanf(str, '%x');这样就可以将字符串'0xFF'转换为十进制整数255。
2.3 格式化输出sscanf函数还可以用于格式化输出,即将一些数据按照指定的格式转换为字符串。
比如,将一个矩阵转换为特定格式的字符串。
代码如下:A = [1, 2, 3; 4, 5, 6; 7, 8, 9];str = sprintf('A = [%d %d %d; %d %d %d; %d %d %d]', A);这样就可以将矩阵A转换为字符串'A = [1 2 3; 4 5 6; 7 8 9]'。
sscanf正则规则
sscanf是C语言中用于解析字符串的函数之一,它可以根据指定的格式规则将字符串解析成所需的数据类型。
它的正则规则包括以下几个方面:
1. 数字格式
在解析数字时,sscanf使用以下格式规则:
%d 表示解析十进制整数
%u 表示解析无符号十进制整数
%o 表示解析八进制无符号整数
%x 表示解析十六进制无符号整数
%f 表示解析浮点数
%e 表示解析科学计数法浮点数
%c 表示解析字符
%s 表示解析字符串
%[] 表示解析字符集
%n 表示计算已解析的字符数
2. 字符串格式
在解析字符串时,sscanf使用以下格式规则:
%s 表示解析字符串,将忽略空格字符,直到遇到下一个非空格字符为止。
3. 宽度限定
在宽度限定中,可以使用数字指定要解析的字符数,例如:
%2s 表示解析最多包含2个字符的字符串
%.*s 表示解析任意宽度的字符串,并将宽度保存在参数中。
4. 精度限定
在精度限定中,可以使用数字指定要解析的精度的位数或小数位数,例如:
%.2f 表示解析浮点数时保留两位小数
%.5s 表示解析字符串时最多解析5个字符
5. 符号格式
在符号格式中,可以使用以下格式规则:
%+ 表示要求必须是有符号的数值
%- 表示要求必须是有符号的数值,并且需要从低位到高位解析。
6. 特殊格式
除了上述格式规则之外,还有一些特殊的格式规则:
%n 表示计算已解析的字符数,并将该值存储在参数中。
%t 表示跳过一个字符。
C语言中的输入输出函数总结1. scanf(函数:scanf(函数是C语言中用于从键盘输入数据的函数。
它可以根据格式字符串从键盘读取不同类型的数据,如整数、浮点数、字符等。
例如,scanf("%d", &num)将从键盘读取一个整数,并将其存储在变量num中。
2. printf(函数:printf(函数是C语言中用于将数据输出到屏幕上的函数。
它可以根据格式字符串将不同类型的数据以特定格式打印输出。
例如,printf("Hello, World!")将在屏幕上打印出"Hello, World!"。
3. gets(函数:gets(函数用于从键盘读取字符串。
它会一直读取字符,直到遇到换行符为止,并将字符串存储在给定的字符数组中。
要注意的是,gets(函数不会检查数组的大小,因此可能导致缓冲区溢出。
为了避免这种情况,最好使用fgets(函数。
4. fgets(函数:fgets(函数也用于从键盘读取字符串,但是它是安全的。
它会读取指定数量的字符,并将其存储在给定的字符数组中。
如果读取的字符数超过了数组的最大长度,多余的字符会被截断。
fgets(函数还会将换行符存储在字符串中,因此需要手动去掉换行符。
5. puts(函数:puts(函数用于将字符串输出到屏幕上,并自动在末尾添加一个换行符。
puts(函数仅适用于输出字符串,不适用于其他类型的数据。
6. putchar(函数:putchar(函数用于将单个字符输出到屏幕上。
它接受一个字符参数,并将其打印到屏幕上。
例如,putchar('A')将在屏幕上打印字母A。
7. getchar(函数:getchar(函数用于从键盘读取单个字符。
它会阻塞程序的执行,直到用户输入一个字符,并返回该字符。
8. sscanf(函数:sscanf(函数用于从一个字符串中读取数据。
它与scanf(函数的用法类似,但从字符串中读取数据而不是从键盘。
sscanf_s函数的用法sscanf_s函数是C语言标准库中的一个函数,用于将字符串解析为指定的格式,可以用来读取字符串中的数据,类似于scanf函数,但是sscanf_s函数相比于scanf函数更加安全,提供了更多的错误检测机制。
```cint sscanf_s(const char *str, const char *format, ...);```其中,str是要解析的字符串,format是格式字符串,用于指定解析的格式,...是格式字符串中的转换说明符对应的参数。
下面是sscanf_s函数的具体用法和一些注意事项:1.基本用法可以使用sscanf_s函数来解析字符串中的各种数据类型,如整数、浮点数、字符等。
```c#include <stdio.h>int maichar str[] = "hello world 123 3.14";char data[20];int num;float pi;printf("data: %s\n", data);printf("num: %d\n", num);printf("pi: %f\n", pi);return 0;```输出结果为:```data: hellonum: 123```通过格式字符串"%s %d %f"来指定解析的格式,%s表示字符串,%d 表示整数,%f表示浮点数。
可以通过&运算符获取变量的地址传递给sscanf_s函数。
2.安全性检查```c#include <stdio.h>int maichar str[] = "hello world 123 3.14";char data[5];int num;float pi;printf("data: %s\n", data);printf("num: %d\n", num);printf("pi: %f\n", pi);return 0;```输出结果为:```data: hellnum: 123```在上面的例子中,将data的最大宽度设置为4,所以只读取了字符串"hell",省略了末尾的字符"o"。
sscanf,sscanf_s 及其相关用法 #include<stdio.h> 定义函数 int sscanf (const char *str,const char * format,........); 函数说明 sscanf()会将参数 str 的字符串根据参数 format 字符串来转换并格式化数据。
格式转换形式请参 考 scanf()。
转换后的结果存于对应的参数内。
返回值 成功则返回参数数目,失败则返回-1,错误原因存于 errno 中。
返回0表示失败 否则,表 示正确格式化数据的个数 例如:sscanf(str,"%d%d%s", &i,&i2, &s); 如果三个变成都读入成 功会返回3。
如果只读入了第一个整数到 i 则会返回1。
证明无法从 str 读入第二个整数。
main() { int i; unsigned int j; char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”; char s[5]; sscanf(input,”%d %x %5[a-z] %*s %f”,&i,&j,s,s); printf(“%d %d %s ”,i,j,s); } 执行 10 27 aaaaa 大家都知道 sscanf 是一个很好用的函数,利用它可以从字符串中取出整数、浮点数和字符串等等。
它的使用方法简单, 特别对于整数和浮点数来说。
但新手可能并不知道处理字符串时的一些高级用法, 这里做个简要说明吧。
1. 常见用法。
charstr[512]={0}; sscanf("123456","%s",str); printf("str=%s",str); 2. 取指定长度的字符串。
如在下例中,取最大长度为4字节的字符串。
sscanf("123456","%4s",str);printf("str=%s",str); 3. 取到指定字符为止的字符串。
Sscanf 函数sscanf() - 从一个字符串中读进与指定格式相符的数据.函数原型:Int sscanf( string str, string fmt, mixed var1, mixed var2 ... );int scanf( const char *format [,argument]... );说明:sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。
其中的format可以是一个或多个{%[*] [width] [size]type | ' ' | '\t' | '\n' | 非%符号}注:1、* 亦可用于格式中, (即%*d 和%*s) 加了星号(*) 表示跳过此数据不读入. (也就是不把此数据读入参数中)2、{a|b|c}表示a,b,c中选一,[d],表示可以有d也可以没有d。
3、width表示读取宽度。
4、参数的size: 常用的有hh表示单字节size,h表示2字节size,其他详见man sscanf或msdn5、type :这就很多了,就是%s,%d之类。
控制字符说明%c 一个单一的字符%d 一个十进制整数%i 一个整数%e, %f, %g 一个浮点数%o 一个八进制数%s 一个字符串%x 一个十六进制数%p 一个指针%n 一个等于读取字符数量的整数%u 一个无符号整数%[] 一个字符集%% 一个精度符6、特别的:%*[width] [{h | l | I64 | L}]type 表示满足该条件的被过滤掉,不会向目标参数中写入值支持集合操作:%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)%[aB'] 匹配a、B、'中一员,贪婪性%[^a] 匹配非a的任意字符,贪婪性还是用例子说话:#include <stdio.h>int main(){char buf[512] = {0};//1. 常见用法。
sscanf分割字符串⽤法总结最近⼀直在写加载配置⽂件的代码,⼤多⽤sscanf函数来分割字符串,学习和总结⼀下它的⽤法:基本⽤法通过ssacnf()语句可以找到和它前⾯匹配的语句然后打印出后⾯需要的东西,基本格式为%[set],表⽰将接收⼀个由set指定格式的字符串,其中set表⽰可接受的字符集合。
set⼀般有两种情况:(1)%[^set]表⽰⾮,即在输⼊字符串中匹配不在set字符集合的所有字符,遇见set字符集中的字符即停⽌;(2)%[set],匹配输⼊字符串中所有在set字符集中的字符,遇见⾮set字符集的字符时即停⽌。
如:sscanf(buf,"%[^&]",str); //当输⼊的字符中出现"&"时停⽌匹配,如果输⼊hello&world,则str=hello;sscanf(buf,"%[^290#]",str); //当输⼊aidc#ad时,则str=aidc,即当输⼊出现了"#"时不再将输⼊内容放⼊str;sscanf(buf,"%[dlza#i]",str) // 如果不是这⼏个字符则停⽌匹配,如当输⼊ai#dcad时,str=ai#d,因为c不在[dlza#i]中.特殊情况:(1)如果要匹配"^"时,当然不能直接放在[]中,所以可以⽤%[ab^cd]这种⽅式,(2)当要匹配右⽅括号"]"时,应把其放在set中第⼀个位置,如"%[]abc]"表⽰匹配的字符集为{], a, b, c},⼜如"%[^]abc]"表⽰匹配所有⾮"], a, b, c"中的字符(3)另外,还可以使⽤"-" 如%[a-z]表⽰只匹配abcd....yz等⼩写的字母;%[0-9]表⽰只匹配0,1,2...9等数字;(4) * 表⽰跳过.注意 : “-”的字符只有在其左右两边都有有效字符时才有这个作⽤,否则被认为是普通字符,如“a-c-e-g”匹配的字符为{a, b, c, -, e, f, g},这样也为输⼊“-”字符提供了⽅法。
scanf格式控制的完整格式:% * m l或h 格式字符①格式字符与printf函数中的使用方式相同,以%d、%o、%x、%c、%s、%f、%e,无%u格式、%g格式。
②可以指定输入数据所占列宽,系统自动按它截取所需数据。
如:scanf(“%3d%3d”,&a,&b);输入:123456系统自动将123赋给a,456赋给b。
③%后的“*”附加说明符,用来表示跳过它相应的数据。
例如:scanf(“%2d%*3d%2d”,&a,&b);如果输入如下信息:1234567。
将12赋给a,67赋给b。
第二个数据”345”被跳过不赋给任何变量。
④输入数据时不能规定精度,例如:scanf(“%7.2f”,&a);是不合法的,不能企图输入:12345.67而使a的值为12345.67。
------------------相关-------------------输入数据流分隔①根据格式字符的含义从输入流中取得数据,当输入流中数据类型与格式字符要求不符时,就认为这一项结束。
如:scanf(“%d%c%f”,&a,&b,&c);如果输入如下信息:1234r1234.567则scanf函数在接收数据时发现”r”类型不匹配,于是把”1234”转换成整型赋值给a,把”r”赋给变量b,最后把”1234.567”转换成实型数据赋给c。
②根据格式项中指定的域宽分隔出数据项。
如语句:scanf(“%2d%3f%4f”,&a,&b,&c);如果输入如下信息:123456789012345则scanf函数在接收数据时根据域宽把12赋值给a,345赋值给b,6789赋值给c。
③隐示分隔符。
空格、跳格符(’\t’)、换行符(’\n’)都是C语言认定的数据分隔符。
④显示分隔符。
在scanf函数的两个格式说明项间有一个或多个普通字符,那么在输入数据时,在两个数据之间也必须以这一个或多个字符分隔。
字符串的输入的主流函数:一、scanf(); 二、cin; 三、gets(); 四、getline(); 五、sscanf()。
一、scanf("%s",str);遇见空格或换行就停止。
#include<stdio.h>int main(){char str[100];while(true){scanf("%s",str);printf("%s\n",str);}return 0;}输入:123 456输出:123456二、cin>>str;与scanf();相似遇见空格或换行就停止;以文件结束。
三、gets(str);gets(str)函数与scanf("%s",&str) 相似,但不完全相同,使用scanf("%s",&s) 函数输入字符串时存在一个问题,就是如果输入了空格会认为字符串结束,空格后的字符将作为下一个输入项处理,但gets()函数将接收输入的整个字符串直到遇到换行为止或文件结束。
四、getline(cin,str);需要加头文件#include<stdlib.h> ;而且str 必须是string类型;读入一行以文件或换行结束。
五、sscanf();1、sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。
2、%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)%[aB'] 匹配a、B、'中一员,贪婪性%[^a] 匹配非a的任意字符,贪婪性3、用法例子a. 常见用法。
char buf[512] ;sscanf("123456 ", "%s", buf);//此处buf是数组名,它的意思是将123456以%s的形式存入buf中!printf("%s\n", buf);结果为:123456b. 取指定长度的字符串。
#include<stdio.h>定义函数int sscanf (const char *str,const char * format,........);函数说明sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。
格式转换形式请参考scanf()。
转换后的结果存于对应的参数内。
返回值成功则返回参数数目,失败则返回-1,错误原因存于errno中。
返回0表示失败否则,表示正确格式化数据的个数例如:sscanf(str,"%d%d%s", &i,&i2, &s); 如果三个变成都读入成功会返回3。
如果只读入了第一个整数到i则会返回1。
证明无法从str读入第二个整数。
main(){int i;unsigned int j;char input[ ]=”10 0x1b aaaaaaaa bbbbbbbb”;char s[5];sscanf(input,”%d %x %5[a-z] %*s %f”,&i,&j,s,s);printf(“%d %d %s ”,i,j,s);}执行10 27 aaaaa大家都知道sscanf是一个很好用的函数,利用它可以从字符串中取出整数、浮点数和字符串等等。
它的使用方法简单,特别对于整数和浮点数来说。
但新手可能并不知道处理字符串时的一些高级用法,这里做个简要说明吧。
1. 常见用法。
charstr[512]={0};sscanf("123456","%s",str);printf("str=%s",str);2. 取指定长度的字符串。
如在下例中,取最大长度为4字节的字符串。
sscanf("123456","%4s",str);printf("str=%s",str);3. 取到指定字符为止的字符串。
如在下例中,取遇到空格为止字符串。
sscanf("123456abcdedf","%[^]",str);printf("str=%s",str);4. 取仅包含指定字符集的字符串。
如在下例中,取仅包含1到9和小写字母的字符串。
sscanf("123456abcdedfBCDEF","%[1-9a-z]",str);printf("str=%s",str);5. 取到指定字符集为止的字符串。
如在下例中,取遇到大写字母为止的字符串。
sscanf("123456abcdedfBCDEF","%[^A-Z]",str);printf("str=%s",str);//////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////可以用如下代码将字符串形式的ip地址转换为四个整数:1char * inputIp2int ip[4];3sscanf_s(inputIp, "%d.%d.%d.%d", &ip[0], &ip[1],&ip[2],&ip[3]);注意sscanf_s,当读入的类型是整数或其它长度可以确定的类型时,不能在类型后面跟上长度,但是对于字符串类型(char *)长度无法得知则必须在类型后面明确指出字符串的最大长度(即可以容纳的空间)。
举例如下:4// crt_sscanf_s.c5// This program uses sscanf_s to read data items6// from a string named tokenstring, then displays them.78#include <stdio.h>9#include <stdlib.h>1011int main( void )12{13char tokenstring[] = "15 12 14...";14char s[81];15char c;16int i;17float fp;1819 // Input various data from tokenstring:20 // max 80 character string plus NULL terminator21 sscanf_s( tokenstring, "%s", s, _countof(s) );22 sscanf_s( tokenstring, "%c", &c, sizeof(char) );23 sscanf_s( tokenstring, "%d", &i );24 sscanf_s( tokenstring, "%f", &fp );2526 // Output the data read27 printf_s( "String = %s\n", s );28 printf_s( "Character = %c\n", c );29 printf_s( "Integer: = %d\n", i );30 printf_s( "Real: = %f\n", fp );31}对于多个字符串读入的情况,代码如下:32sscanf_s(inputString, "%s.%s.%s.%s", s1, s1.length, s2, s2.length, s3, s3.length, s4, s4.length);sscanf 函数非常好用,居然我以前一直不知道这个函数。
最近朋友用VS2008写程序时用到这个函数的安全版本 sscanf_s ,却出现异常问题,无法解析字符串不说,还会崩溃。
int sscanf_s(const char *buffer,const char *format [,argument ] ...);这是MSDN里面关于函数的定义,没有继续详细查看后面的备注,以及实例的情况下。
根本感觉不到sscanf 与 sscanf_s 的区别。
以为仍然是像sscanf 一样使用,以致出现奇怪问题。
Example:// crt_sscanf_s.c// This program uses sscanf_s to read data items// from a string named tokenstring, then displays them.#include <stdio.h>#include <stdlib.h>int main( void ){char tokenstring[] = "15 12 14...";char s[81];char c;int i;float fp;// Input various data from tokenstring:// max 80 character string plus NULL terminatorsscanf_s( tokenstring, "%s", s, _countof(s) );sscanf_s( tokenstring, "%c", &c, sizeof(char) );sscanf_s( tokenstring, "%d", &i );sscanf_s( tokenstring, "%f", &fp );// Output the data readprintf_s( "String = %s\n", s );printf_s( "Character = %c\n", c );printf_s( "Integer: = %d\n", i );printf_s( "Real: = %f\n", fp );}直到看完整个文档,看到这个实例,才发现原来还有猫腻!sscanf_s 取值的时候,需要在每个取值后面指定取值的最大大小。
在使用VS2005编译一个程序时,出现了很多警告,说是用的函数是不安全的,应当使用安全版本,即函数名称增加“_s”的版本。
警告内容:warning C4996: 'sscanf': This function or variable may be unsafe. Consider using sscanf_s instead.据了解,“_s”版本函数是微软后来对c++做得扩展,用来替代原先不安全的函数,例如:printf、scanf、strcpy、fopen等等。
详细参考:ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_vccrt/html/d9568b0 8-9514-49cd-b3dc-2454ded195a3.htm原来安全版本的函数,对参数和缓冲边界做了检查,增加了返回值和抛出异常。
这样增加了函数的安全性,减少了出错的几率。
同时这也意味着在使用这些函数时,有时你不得不输入更多的关于缓冲区大小的参数,多敲几下键盘能换来更少的麻烦,值得!下面总结了sscanf的以及sscanf_s的常用方法,也体现了“_s”版本函数与原函数的特别之处:1、sscanf和scanf的不同是输入来源,前者是一个字符串,后者则是标准输入设备2、sscanf的使用,以解析时间字符串为例,将字符串“2009-01-02_11:12:13”解析为整型年月日时分秒//定义char cc;tm tm_temp={0};string stime("2009-01-02_11:12:13");//(1) 必须严格按照分隔符形式匹配填写,若遇到不匹配项则终止解析sscanf(stime.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d",&tm_temp.tm_year,&tm_temp.tm_mon,&tm_temp.tm_mday,&tm_temp.tm_hour,&tm_temp.tm_min,&tm_temp.tm_sec);//(2) 可以不按照分割符号形式填写,字符数必须一致,例如可以正确解析“2009/01/02_11:12:13”sscanf(stime.c_str(), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d",&tm_temp.tm_year, &cc,&tm_temp.tm_mon, &cc,&tm_temp.tm_mday, &cc,&tm_temp.tm_hour, &cc,&tm_temp.tm_min, &cc,&tm_temp.tm_sec);//(3) 可以不按照分割符号形式填写,字符数必须一致,同上,%1s可以等同于%csscanf(stime.c_str(), "%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d",&tm_temp.tm_year, &cc,&tm_temp.tm_mon, &cc,&tm_temp.tm_mday, &cc,&tm_temp.tm_hour, &cc,&tm_temp.tm_min, &cc,&tm_temp.tm_sec);//(4) 可以不按照分割符形式和数量填写,类型必须一致,例如可以正确解析“2009/01/02___11:12:13”//这里使用了sscanf的正则表达式,与通用的正则表示类似但不完全相同,%*c表示忽略连续多个字符sscanf(stime.c_str(), "%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d",&tm_temp.tm_year,&tm_temp.tm_mon,&tm_temp.tm_mday,&tm_temp.tm_hour,&tm_temp.tm_min,&tm_temp.tm_sec);3、sscanf_s的使用//定义char cc[2];tm tm_temp={0};string stime("2009-01-02_11:12:13");//(1) 与sscanf第一种方法相同,可以使用"%4d-%2d-%2d_%2d:%2d:%2d"格式匹配解析sscanf_s(stime.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d",&tm_temp.tm_year,&tm_temp.tm_mon,&tm_temp.tm_mday,&tm_temp.tm_hour,&tm_temp.tm_min,&tm_temp.tm_sec);//(2) 使用%c格式对数据解析时,必须对相应的缓冲区增加长度参数,否则将会出错sscanf_s(stime.c_str(), "%4d%c%2d%c%2d%c%2d%c%2d%c%2d",&tm_temp.tm_year, &cc, 1,&tm_temp.tm_mon, &cc, 1,&tm_temp.tm_mday, &cc, 1,&tm_temp.tm_hour, &cc, 1,&tm_temp.tm_min, &cc, 1,&tm_temp.tm_sec);//(3) 使用%s格式对数据解析时,缓冲长度必须大于字符串长度,否则不予解析sscanf_s(stime.c_str(), "%4d%1s%2d%1s%2d%1s%2d%1s%2d%1s%2d",&tm_temp.tm_year, &cc, 2,&tm_temp.tm_mon, &cc, 2,&tm_temp.tm_mday, &cc, 2,&tm_temp.tm_hour, &cc, 2,&tm_temp.tm_min, &cc, 2,&tm_temp.tm_sec);//(4) 与sscanf一样,sscanf_s同样支持正则表达式sscanf_s(stime.c_str(), "%4d%*c%2d%*c%2d%*c%2d%*c%2d%*c%2d",&tm_temp.tm_year,&tm_temp.tm_mon,&tm_temp.tm_mday,&tm_temp.tm_hour,&tm_temp.tm_min,&tm_temp.tm_sec);通过以上对比sscanf与sscanf_s的使用,可以看出后者对缓冲区安全有了更多的考虑,从而避免了许多不经意的烦恼。