2015-04-02 32 views
0

我是新來的底層編程,並已堅持了以下問題:如何比較和子從C字符串解析數

我得到了以下格式的字符串:

?cmd=ASET&<hour>&<minute> 

小時和分鐘值總是由2個十進制數組成。 所以可以接收該字符串的例子是:

"?cmd=ASET&08&30" 

我試圖寫一個聲明,如果承認該字符串開頭和改變兩個全局變量稱爲分鐘和小時「CMD = ASET?」到字符串中的值。我一直試圖用strtok()來做到這一點,但迄今爲止還沒有任何運氣。所以我的if語句的全球佈局是:

if (String starts with "?cmd=ASET") { 
    minute = value found in the string; 
    hour = value found in the string; 
} 

我真的很感激任何幫助。

+0

請點擊適合您的答案旁邊的灰色複選標記以解決您的問題。 – clearlight 2015-04-02 19:43:56

回答

4

嘗試類似這樣的操作,其中cmd是char *或char []類型變量。請注意,strncmp()strcmp()安全。通常,在C編程中,您希望使用限制長度的函數變體,以避免堆棧溢出攻擊和其他安全風險。而且,由於字符串到數字函數可能會失敗,如果給定錯誤輸入,最好使用可以檢查其狀態的表單,這就是爲什麼不建議使用atoi()atol()sscanf()允許檢查狀態與strtol()一樣,因此它們都可以接受。

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

int 
main() 
{ 
    char *string = "?cmd=ASET&12&30"; 
    #define ASET_CMD "?cmd=ASET" 
    int hour = 0, minute = 0; 
    if (strncmp(string, ASET_CMD, strlen(ASET_CMD)) == 0) { 
     if (sscanf(string + strlen(ASET_CMD), "&%d&%d", &hour, &minute) != 2) { 
      printf("Couldn't parse input string"); 
      exit(EXIT_FAILURE); 
     } 
    } 
    printf("hour: %d, minute: %d\n", hour, minute); 
    return(EXIT_SUCCESS); 
} 

$ cc -o prog prog.c 
$ ./prog 
hour: 12, minute: 30 
+0

即使窗戶讓你擺脫它。 'main'是'int'類型的函數,實際上應該返回一個值給shell。 (例如'return 0;')否則,很好的答案。 – 2015-04-02 19:45:45

+0

應該初始化'小時'和'分鐘'。內部if還缺少一個花括號。 – Forss 2015-04-02 19:47:08

+0

還應該包含'stdlib.h'來防止未定義的對''exit''的引用。 – 2015-04-02 19:48:59

0

有一個函數atoi(),它從字符串中返回整數。
您可以像

char string[16]; 
strcpy(string, "?cmd=ASET&08&30"); 
if (String starts with "?cmd=ASET") { 
    hour = atoi(string+10); 
    minute = atoi(string+13); 
} 

其中+10是小時和位置爲+13分鐘解析字符串。
這裏是一個工作示例:

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

int main() 
{ 
    int hour, minute; 
    char string[16]; 
    strcpy(string, "?cmd=ASET&08&30"); 

    /* Check if string contains ?cmd=ASET */ 
    if (strstr(string, "?cmd=ASET") != NULL) 
    { 
     /* Parse minute and hour */ 
     hour = atoi(string+10); 
     minute = atoi(string+13); 

     /* Print output */ 
     printf("Minute: %02d \nHour: %02d\n", minute, hour); 
    } 
} 
+2

使用小時和分鐘的數字偏移很不妥。命名常量會更好。此外,'atoi()'可能會失敗。 'strtol()'被認爲是一個更好更安全的字符串整數轉換函數,它的狀態可以被檢查。 – clearlight 2015-04-02 19:28:30

+0

另一個問題是,對於'strstr()',你正在尋找的字符串可能在字符串中的任何地方,所以如果前面有垃圾,這可能會在代碼或輸入的其他地方標記爲實質性錯誤,也許,你的代碼會錯過它。這就是爲什麼考慮到問題中描述的輸入語法,strncmp()是更好的選擇。 – clearlight 2015-04-02 19:50:09

1

如果sscanf()可用於OP,考慮:

unsigned hour, minute; 
int n; 
int cnt = sscanf(buffer, "?cmd=ASET&%2u&%2u%n", &hour, &minute, &n); 
if (cnt == 2 && buffer[n] == 0) Success(); 
else Failure(); 

cnt將有2的值,如果前綴匹配和2號在那裏發現的。
n檢測字符串中是否存在任何附加字符。