[英]C programming: How to use sscanf with a ':' delimiter?
我一直在嘗試使用sscanf
從輸入文本中提取小時,秒和分鍾。 執行sscanf
函數后,只有保留秒數的s
變量具有正確的值。 帶有小時和分鍾的h
和m
僅保留零。 請在下面建議對我的代碼進行更改。
char text[20];
if (fgets(text, sizeof text, stdin)!= NULL){
char* newline = strchr(text, '\n');
if (newline != NULL){
*newline = '\0';
}
}
uint8_t s = 0;
uint8_t m = 0;
uint8_t h = 0;
sscanf(text, "%02i:%02i:%02i",&h,&m,&s);
注意在調試器中,文本具有正確的值。
該程序:
#include <stdio.h>
int main(void)
{
const char hhmmss[] = "10:32:54";
int hh, mm, ss;
if (sscanf(hhmmss, "%i:%i:%i", &hh, &mm, &ss) != 3)
printf("Failed to scan 3 values from '%s'\n", hhmmss);
else
printf("From <<%s>> hh = %d, mm = %d, ss = %d\n", hhmmss, hh, mm, ss);
return 0;
}
給出以下輸出:
From <<10:32:54>> hh = 10, mm = 32, ss = 54
%02i
轉換也應該起作用,但是數字有點多余。
修改后的問題表明,變量的類型為uint8_t
,在這種情況下,必須使用<inttypes.h>
的正確轉換說明符:
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
const char hhmmss[] = "10:32:54";
uint8_t s;
uint8_t m;
uint8_t h;
if (sscanf(hhmmss, "%02" SCNi8 ":%02" SCNi8 ":%02" SCNi8, &h, &m, &s) != 3)
printf("Failed to scan 3 values from '%s'\n", hhmmss);
else
printf("From <<%s>> h = %d, m = %d, s = %d\n", hhmmss, h, m, s);
return 0;
}
這將產生與以前相同的輸出。 對於任何scanf()
函數家族,至關重要的是,格式轉換說明符必須與要傳遞給函數的指針的類型相匹配。 由於默認的整數提升(特別是),您scanf()
printf()
的很多不匹配printf()
當然是比較),但是scanf()
寬容度要低得多。
@Jonathan Leffler的回答是完全正確的,但是...
除非可能在已知的拋出明天代碼中使用,否則永遠不要使用scanf
或fscanf
或sscanf
來分析來自文件句柄或字符串的輸入。 它們太容易出錯並且很難控制。 對於scanf
的各種問題的詳盡總結,我推薦本系列文章 。 一些要點:
getchar
。 scanf
會遇到gets
所有緩沖區溢出問題。 scanf
的解析容易出錯並且難以使用。 請改用strtoul
和strtod
。 該怎么辦?
gets
更好的方法讀取自己的輸入,即沒有緩沖區溢出問題。 不要試圖將輸入字節與解釋字節結合起來。 strcspn
, strspn
和stroul
和strtod
組合以及一些自定義代碼來掃描輸入。 有時候這也很麻煩,但是到那時,您通常需要構建某種輸入語言,但無論如何都需要更多的通用技術。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.