不一樣的sscanf函式
今天在看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<stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> 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<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
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完全是由我們自己掌控的啦~