2012-02-12 55 views
0

我一直在嘗試使用sscanf從輸入文本中提取小時,秒和分鐘。執行sscanf功能後,只有s變量持有秒數才具有正確的值。 hm其中只有小時和分鐘只能保持零。請在下面建議更改我的代碼。C編程:如何使用帶':'分隔符的sscanf?

 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); 

注意在調試器中,文本具有正確的值。

+0

我們可以看看你如何聲明並初始化h,m和s嗎? – Lefteris 2012-02-12 05:50:44

回答

3

這個程序:

#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()函數系列中的任何一種,格式轉換說明符與您傳遞給函數的指針類型相匹配至關重要。 printf() - 當然相比 - 你可以逃脫很多不匹配 - 因爲默認整數(尤其是)促銷,但scanf()是寬容少得多。

2

@Jonathan萊弗勒的答案是完全正確的,但是......

你應該從未使用scanffscanfsscanf在也許是從文件句柄或字符串解析輸入,除了已知的對是 - 拋棄明天的代碼。他們太容易出錯,難以控制。有關scanf的各種問題的詳盡摘要,我推薦this series of articles。一些亮點:

  • 如果您需要閱讀單個字符,請使用getchar
  • 如果你想讀取一個字符串,scanf有所有的緩衝區溢出問題gets
  • 如果你想讀取數字,scanf的解析是容易出錯和難以使用的。改爲使用strtoulstrtod
  • 如果你有更復雜的輸入,一切都會變得更糟。

怎麼辦?

  • 使用比gets更好的東西來閱讀您自己的輸入,也就是說,沒有緩衝區溢出問題。不要試圖結合獲取字節和解釋它們。
  • 結合strcspn,strspnstroulstrtod結合一些自定義代碼來掃描輸入。

有時候這也是一種拖拽,但到那個時候,你通常會建立某種輸入語言,無論如何需要更多的通用技術。

+1

我寧願使用'sscanf()'而不是'strtok()'。至少,'strtok()'在類庫函數等任何東西中都是有毒的。你必須知道被調用的庫函數使用它,並確保代碼中沒有其他東西在同一時間使用它。邪惡! (在可用的情況下,'strtok_r()'更安全,更安全;至少可用,但它仍然存在一些問題。) – 2012-02-12 06:41:12

+0

是的,我不關心strtok,也可能永遠不會使用它,但它的問題在某些方面與scanf問題是正交的。也就是說,我已經刪除了參考。 – 2012-02-12 06:50:16