[爆卦]Sscanf return value是什麼?優點缺點精華區懶人包

為什麼這篇Sscanf return value鄉民發文收入到精華區:因為在Sscanf return value這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者tropical72 (藍影)看板C_and_CPP標題Re: [問題] sscanf的奇怪問題...


恕刪

james732:推板主04/29 13:53
bestwishes:我也喜歡這種作法 在JAVA底下尤其好做 04/29 13:57
xatier:推板主,這個解更棒 04/29 14:25
piness:謝謝版主!!又多學了一招04/29 14:35
tropical72:我比較建議原本的空白先取代成 ASCII(255),看起來也是04/29 20:53
tropical72:空白,再用ASCII(20)去取代沒意義的東西.再將255取回來,04/29 20:53
tropical72:我常遇到的問題便是原先空白不可抹掉04/29 20:54
tropical72:取回動作通常不做,因看起來都是 space XD04/29 20:55

修正,上述的 ASCII(20) 應為 ASCII(32),進制記錯

: 可是這會有signed/unsigned的問題, 請問有除了255以外的解決方案嗎?
: 想到用 '\t' 之類的應該也可以, 只是沒試過~

的確 signed/unsigned 問題之前沒實際考量過,
但若單純為 sscanf 使用,使用 ASCII 255 應為合理,
當然較保險的方式是 #define / const 一個出來

const unsigned char FALSE_SPACE_UNI = (unsigned char)(0xff)
const char FALSE_SPACE_SIG = ( char)(0xff)

之所以不再取代回去,純粹是因為「看起來像」是 space,實際上卻不是 ASCII(32),
若考慮寫入檔案日後仍有維護之需求,才有必要再將 ASCII(255) 換回 ASCII(32)

至於再換成 '\t' ,那又回到了解這問題的原點:
sscanf\scanf 是以 white space 為斷點,其中便包含了 ' ', '\t', '\n'
所以換成 '\t' 應不適用於這裡
三個字元,會找一個「看起來是空白,實際上卻不是空白」的去取代,
純粹是為了避開此問題,目前用這種方式處理倒是還沒出過包,
如此方式有問題的話也請不吝指正,避免日後出包不知道怎麼死的。

程式碼大概如下

#include <stdio.h>
#include <string.h>

void replace(char *str)
{
char* ptr=strchr(str, ' ');
while(ptr!=NULL){
*ptr = 255;
++ptr;
ptr = strchr(ptr, ' ');
}
}
int main()
{
char demo[] = "goodbye my love\nptt cpp\nthis is a test\n";
char str1[200], str2[200], str3[200];
printf("%s\n", demo), replace(demo);
sscanf(demo, "%s%s%s", str1, str2, str3);
printf("str1:%s\n", str1);
printf("str2:%s\n", str2);
printf("str3:%s\n", str3);
return 0;
}

此處便不把 str1, str2, str3 之 255 replace 回來,輸出結果「看」起來正常.

--
YouLoveMe() ? LetItBe() : LetMeFree();

--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.73.222
※ 編輯: tropical72 來自: 180.177.73.222 (04/29 21:35)
loveme00835:) 04/29 21:54
xatier:) 04/30 12:41
scan33scan33:其實我不太懂為什麼大家都不用regex? 04/30 15:13
loveme00835:因為對象是 CFL 不是 RL, function call expression 04/30 15:18
loveme00835:多一個引數可能就不適用了, 倒不如先做個陽春版 04/30 15:19
scan33scan33:@@哪裡CFL了...原po要得東西明明就可以用RL表示 04/30 15:36
scan33scan33:用regex一行寫完不是很好? 04/30 15:37
scan33scan33:我說的是原來問這個問題的人 04/30 15:42
loveme00835:你解決的是"這個"問題, 不是"這類"問題, 原因我在原po 04/30 15:43
loveme00835:那篇推文裡有說 04/30 15:43
scan33scan33:如果你是說那個理由的話,基本上只要args數目fixed 04/30 15:47
scan33scan33:函數名稱跟args變化的空間很大 04/30 15:47
scan33scan33:另外也可以用sscanf的return value來trace是否讀成功 04/30 15:48
scan33scan33:我是覺得如果是RL可以處理的,那就沒必要用CFL方式處 04/30 15:50
scan33scan33:理。除非有特別需求 04/30 15:51

吾人非不用 regex, 但以上述的例子而言
字串若為 "字串1 還是字串1\t字串2 還是字串2\t字串3 還是字串3\n"
想抓成三份以 \t 為切割,保留中間之空白,這要怎麼做?

(1) fgets + strchr (2) fgets + strtok
(3) fgets + replace + sscanf

原意與 loveme00835 同,唯考慮我應用到之情況,space 「不要分割」
( 試想如果是 csv file 中間的 space 保留問題 ),以 regex , how to ??
先用 fscanf 再用 strcat ?
parasing 僅為經驗分享而已, 歡迎不吝指教與建議.
loveme00835:好像有錯字? 文言文...Orz我 還老師了 04/30 16:21
錯字已修正, 謝謝指正
scan33scan33:我是覺得沒有double pass的必要... 04/30 16:21
※ 編輯: tropical72 來自: 180.177.73.222 (04/30 16:24)

你可能也想看看

搜尋相關網站