2014-03-28 63 views
1

我想讀取由一組數字組成的字符串,後跟一個字符串,並用其他一些基本文本包裝。用sscanf讀取字符串的其餘部分

換句話說,該行的格式是這樣的:

Stuff<5,10,-5,8,"Test string here."> 

天真,我想:

sscanf(str,"Stuff<%d,%d,%d,%d,\"%s\">",&i1,&i2,&i3,&i4,str2); 

但是經過一番研究,我發現%s應該停止解析時它得到一個空白字符。我找到了this question,但沒有一個答案解決了我遇到的問題:該字符串可能包含任何字符,包括換行符和正確轉義的引號。後者不是問題,如果我可以讓sscanf在我提供的預先分配的緩衝區中的第一個引號之後放置所有內容,我可以自行剝離結尾。

但我該怎麼做?我不能使用%[],因爲它需要一些東西來終止字符串,我唯一想終止它的就是空終止符。所以我想,「嘿,我只是使用空終止符!」但%[\0]作出的編譯器脾氣暴躁:

warning: no closing ‘]’ for ‘%[’ format 
warning: embedded ‘\0’ in format 
warning: no closing ‘]’ for ‘%[’ format 
warning: embedded ‘\0’ in format 

使用類似%*c不會工作,因爲我不知道到底有多少個字符需要採取。我嘗試通過strlen(str),因爲它會少於這個數字,但sscanf返回4,並且沒有任何數據放入str2,這表明也許是因爲長度太長而放棄了,並且沒有打擾。

更新:我想我可以做這樣的事情:

sscanf(str,"Stuff<%d,%d,%d,%d,\"%n",&i1,&i2,&i3,&i4,&n); 
str2 = str+n; 

回答

2

您的更新似乎是一個很好的答案。在使用sscanf得到i1i4後,我打算建議strchr找到第一個報價字符的位置。請注意,您應該始終檢查sscanf的返回值,以確保轉換工作正常。這對於您的建議答案更重要,因爲如果前四次轉換不成功,n將保持未初始化狀態。

-1

這不是實現您想要實現的唯一方法,但可能是最簡單的方法:您需要使用掃描程序。我不會直接用這個答案告訴你解決方案,我會解釋如何使用掃描集,據我所知,你希望能夠自己做。

掃描集%[...]就像%s談到賦值時,他們將值解釋爲字符並將它們存儲到字符數組中。 %s是空白終止的,%[...]是該版本的靈活版本。

有兩種使用掃描儀的方法,第一種使用前面的脫字符號^,第二種使用前面的脫字符號^

當您使用沒有前面插入符號的掃描集^時,放在括號內的字符將是唯一將被讀取,存儲並留下的字符。只要scanf遇到不匹配的字符,該%[...]將會結束。例如:

// input: asdasdasdwasdasd 
char s[100] = { 0 }; 
scanf("%[das]", s); 
printf("%s", s); 
// output: asdasdasd 

當您使用與之前的插入符號^掃描集,搜索反轉。它會讀取,存儲和保留每個角色,直到它到達任何一個在前面的脫字符^之後放下的角色。例如:

// input: abcdefgh^kekQ 
char s[100] = { 0 }; 
scanf("%[^Q^]", s); 
printf("%s", s); 
// output: abcdefgh 

請注意,剩餘字符仍然要在流內讀取,文件指針不會超出導致終止的字符。即對於第一個,getchar();將給出'w',第二個將給出'^'

我希望這將足夠。如果你仍然無法找到出路,那就問問,我可以給你一個解決方案。

1

掃描'\"',然後對於所有不是'\"',然後再'\"'

請務必檢查sscanf()結果並限制測試字符串的長度。

char test_string[100]; 
int n = 0; 
if (sscanf(str, "Stuff<%d,%d,%d,%d, \"%99[^\"]\"> %n", 
     &i1, &i2, &i3, &i4, test_string, &n) == 5 && str[n] == '\0') Good(); 

您嘗試使用"...%[\0]...",從sscanf()點視圖的-,是"...%["
格式從"\0"開始的所有內容都將被忽略。

使用int n = 0,附加" %n"格式字符串,追加&n到的參數和檢查str[n] == '\0'是一個巧妙的方法與sscanf(),以確保正確地解析的整行。注意:"%n"不會加上sscanf()的結果。

相關問題