今天在看UNP卷二的第九章记录上锁的时候,就突然看到了这么一行代码
sscanf(line,"%ld\n",&seqno);
line是一个字符数组,通过read函数和一个文件的fd参数,将这个文件内容存在了line数组里。但是,是真的不明白为什么这个函数后,就把一个long型的seqno的值设置为1了呢?
我感觉好像以前用过这个函数吧,但是,我已经忘记的差不多了。。。在这个例子中我却发现它有点不一般,于是我经过一系列测试,发现其中有一些值得注意的地方:
在网上看到这个函数的解释都是这个样子的
sscanf() 的作用:从一个字符串中读进与指定格式相符的数据.
原型: int sscanf (const char *str,const char * format,........);
说明: sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。转换后的结果存于对应的参数内. 成功则返回参数数目,失败则返回0。
也就是说这个函数通过中间一个参数所设置的匹配规则,将第一个参数里匹配的内容存到最后一个参数中。
这一点一定要首先明确,不要傻逼逼的以为你在第一个参数中输入字符型数据它也会给你转化成整型数据,它只会匹配整型的数并将其输出,如果你输入的都是字符型的话,那么你的返回值将为0,你的第三个参数里面放着的也是0。
好,这一点我们明确了,那我们来写一个程序验证一下吧。
No1.
此时我的1.txt文件内容如下
1 haha heihei houhou 2
测试程序1:
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
char seqo [1000];
int pid,fd;
pid = getpid();
char i[100];
fd = open("/Users/yannie/Desktop/1.txt",O_RDWR,777);
printf("pid = %d,fd = %d\n",pid,fd);
read(fd,seqo,1000);
printf("%s\n",seqo);
int n = sscanf(seqo,"%s",i);
printf(" n = %d,i = %s\n",n,i);
return 0;
}
输出结果如下:
当时看到i=1时,我的心里充满了疑问,what???正常操作不应该是0吗???什么鬼??
于是我把1.txt文本里的东西稍稍做更改,发现
i变成了1hahaheihei,原来是那个空格符的错啊,它将字符串分开了,所以在匹配的时候就变成了1了。此时由于1在字符数组中,所以其也被当作一个字符来看,所以第一个的时候就将其匹配上了。
No.2
我将我的sscanf的第三个参数改为一个整形数i的地址。即修改部分如下:
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
char seqo [1000];
int pid,fd;
pid = getpid();
int i;
fd = open("/Users/yannie/Desktop/1.txt",O_RDWR,777);
printf("pid = %d,fd = %d\n",pid,fd);
read(fd,seqo,1000);
printf("%s\n",seqo);
int n = sscanf(seqo,"%d",&i);
printf(" n = %d,i = %d\n",n,i);
return 0;
}
这时,我们1.txt稍做更改,此时结果为:
i = 123,看来这里由于上一步将其放入一个整型i的地址中,即这一行代码
sscanf(seqo,"%d",&i);
所以,它这里将1当成了一个整数,所以也就存进来了。然而如果此时我们把文件中的1删掉,会发现:
很明显匹配失败了,所以i就等于0了。
到这里我们的思路越来越清晰了。
让我们来看一下UNP上面的示例代码,由于line里存的是前面用read函数通过文件标识符读取的文件内容,所以,这个seqo的值就完全掌控在那个文件的手里。
所以如果我们想让seqo为1的话,就让文本开始为1,然后其他的用空格隔开就好了,所以也就是说这个序列号seqo完全是由我们自己掌控的啦~