2012-03-31 69 views
1

我試圖建立一個開關,我得到一個「表達式必須有整數或枚舉類型」。我猜測在winapi中的開關不使用LPSTR類型的變量?你如何在C中定義一個常量?

char testbuf[ 51 ]; // allocate space for 50 characters + termination 
LPSTR test = testbuf; 
scanf("%50s", test); // read at most 50 characters 
printf("%s", test); 
switch (test) { 
    case "etc" : 
     { 

     } 
    break; 

回答

1

我通常使用的字典模式:

enum { 
    keyETC, 
    keyOther, 
    keyUnknown 
}; 
struct SDictionary{ 
    int key; 
    char *name; 
} dict[] = { 
    { keyETC, "etc" }, 
    { keyOther, "bla" }, 
    { 0 } 
}; 

// lookup 
struct SDictionary *pCandidate = dict; 
int key = keyUnknown; 

while (pCandidate->name) 
{ 
    if (0 == strcmp(test, pCandidate->name) 
    { 
     key = pCandidate->key; 
     break; 
    } 
} 

switch (key) 
{ 
    case keyETC: 
    // .... 
} 
4

這有什麼好做WinAPI的,這是平原C.你可以switch上的積分(intchar和類似)或枚舉類型,就像你的編譯器告訴你的唯一的事情。

如果您需要「切換」字符串,您需要自行構建和使用if/else序列,並使用strcmp或其變體。

0

在常規情況下,你需要將字符串與字符串比較算法,像這樣比較:

if(strcmp(test, "etc") == 0) { 
    ... 
} 

然而,有趣的是,如果字符串可以通過他們的第一個4個字節被唯一標識,你想一個更優化的開關,你可以做花樣這樣的:

#include <Windows.h> 
#include <stdio.h> 

int main(void) 
{ 
    LPSTR test = "etc"; 

    switch(*(DWORD *)test) { 
    case 'cte': 
    puts("etc case"); 
    break; 
    default: 
    puts("not hit"); 
    break; 
    } 

    return ERROR_SUCCESS; 
} 

這將打印etc case到控制檯,因爲我們採取的字符串的指針,並把它作爲一個DWORD指針。指針然後被解引用,並與字符串的值DWORD進行比較。在這種情況下,字符串只有3個字符長,但如果我們考慮結尾的空終止符,它可以由其前4個字節唯一標識。

注意:應該注意的是,這個技巧只適用於允許未對齊訪問內存的體系結構。原因是潛在的字符串可能不是DWORD對齊的。

+0

這是未定義的行爲:你沒有任何擔保的字符數組,其中'測試的第一個字節'指向DWORD對齊。此取消引用操作可能會導致UNALIGNED異常。此外,這不應該與一個大型機器,如果它? – harper 2012-03-31 14:16:53

+0

爲了減輕你對齊的擔憂,'*(WORD *)(test + 1)=='ct'&& *(WORD *)(test)=='te''將評估爲true。普通的'test + 1'和'test'不能用WORD對齊:)系統抽象出未對齊的訪問。有關詳細信息,請參閱此處:http://msdn.microsoft.com/zh-cn/library/aa290049(v=vs.71).aspx。事實上,這就是爲什麼在循環中不對齊的訪問是這樣一個性能殺手! – 2012-03-31 14:20:36

+0

此外,Windows僅在小端機器上運行:http://support.microsoft.com/kb/102025和http://blogs.msdn.com/b/larryosterman/archive/2005/06/07/426334.aspx – 2012-03-31 14:24:27

0

C未對字符數組的情況。只支持整數值。

當您知道要用作開關參數的字符串的長度不超過整數類型的大小時,可以重新解釋char數組的字符作爲數字。

char *test = "etc"; 
int NumericalValue = 0; 
int size = min(sizeof(NumericalValue), strlen(test) + 1); 
memcpy(&NumericalValue, test, size) 

當你有了這個號碼,你可以在switch語句中使用的一些常量:

// you need to adapt the actual values to your architecture's representation of numbers. 
const int keyETC = 0x00635445; 

switch (NumericalValue) 
{ 
case keyETC: 
    puts("etc case"); 
    break; 
default: 
    .... 
}