int num = sscanf(start, "(%s)", buf);
在此,當它遇到一個空白在緩衝器sscanf
返回通過start
指向。你在你輸入的字符串有一個空格:
"([34]xx{4,7}| 1234567890)"
^space here
scanf
返回成功匹配和分配的輸入項目的數量。在這裏,它將返回1
,並且值num
是1
。接下來,用if
塊中的該語句覆蓋buf
中的最後一個字符。
buf[strlen(buf) - 1] = '\0';
這解釋了你的程序的輸出。現在,關於您的代碼的幾件事:
您不需要做memset(buf, 0, LEN);
。只需執行char buf[LEN] = {0};
這將填充空字節的數組。
sscanf
不檢查緩衝區buf
的數組綁定,其中您正在寫入的字符串是sscanf
正在從start
中讀取。如果buf
的大小不夠,sscanf
會嘗試在超出緩衝區buf
的內存中寫入。這會導致未定義的行爲,甚至因非法內存訪問而導致程序崩潰。您應該在格式字符串sscanf
中給出字段寬度以防止緩衝區溢出。
#define STRINGIFY(s) #s // preprocessor command # stringifies the token s
#define XSTRINGIFY(s) STRINGIFY(s)
#define LEN 10 // max buffer length without the null byte
// inside a function
char buf[LEN + 1]; // +1 for the null byte
const char *format = "(" XSTRINGIFY(LEN) "%s)"; // "(%10s)"
int num = sscanf(start, format, buf);
在格式字符串"(%10s)"
的10
意味着至多10
字符被存儲在緩衝器指向buf
然後一個空字節\0
在端自動添加。因此,你不需要在if
塊以下幾點:
buf[strlen(buf) - 1] = '\0'; // overwrites the last char before null byte in buf.
這樣做,事實上,將覆蓋buf
,因爲strlen
不計空字節的最後一個字符。
你得到的實際輸出是多少? – Dipto
如果字符串在末尾沒有\ 0,則不應使用strlen(buf)。 –
''sscanf()'遇到空白時會停止讀取'%s'。 '|'字符後面有一個空格。代碼然後覆蓋'|'字符。 – hmjd