2012-11-08 45 views
2

我有一個解析配置文件的C程序。配置文件允許一些格式爲 option=%any的通配符。如何對C中包含「%」的字符串執行strcmp?

問題是,當我使用strcmp來比較值,我得到一個非法的指令錯誤。

示例程序來說明這一點:

char str1[10]; 
sprintf(str1,"%any"); 

if(strcmp(str1,"%any") == 0) 
     printf("match\n"); 

return 0; 

輸出:

$ ./a.out 
Illegal instruction 

的printf也引發此錯誤。

With printf(「%s \ n」,str1);

輸出是:

$ ./a.out 
0x0.07fff00000001p-1022ny 
Illegal instruction 

我試圖逸出,即使用 「\%任何」,而不是在sprintf的 「%任何」;但這並沒有幫助。

在C++中,與std :: string ==比較,並使用cout打印似乎工作正常。

可能有人請幫我找出如何與C

+1

在'printf()'的每一個不錯的文檔中都記錄了'%'的轉義。爲什麼不只閱讀其中一份文件? – 2012-11-08 14:43:56

+0

不應該關閉太本地化......問如何轉義'%'根本不是本地化的。 – djechlin

+0

@djechlin沒有閱讀文檔使其過於本地化(對於那些不閱讀文檔的人)。 – 2012-11-08 18:20:35

回答

6

它來自sprintf做到這一點。

#include <stdio.h> 

sprintf(str1, "%%any"); 

由於保羅R.說,你可以使用,而strcpy做不擔心這些格式。

+2

更好的是,使用strcpy而不是sprintf。 –

+1

@PaulR Nope,而不是'strncpy()'或'snprintf()'。我們應該避免使用不安全的函數(即那些不需要長度參數的函數)。 – 2012-11-08 14:43:25

+3

@ H2CO3:我贊同'snprintf',但不贊同'strncpy'。這個函數不是爲了空字符串而設計的。 – md5

1

在這種情況下,你應該寫下列之一:

char str1[10] = "%any"; 
char str1[] = "%any"; // str1 has size 5 
const char *str1 = "%any"; // str1 points to a string literal 

在格式化字符串%a是一個十六進制浮點格式。除了沒有提供double參數(導致未定義的行爲)之外,這可能會寫入超過10個字節,因此會超出緩衝區str1(導致未定義的行爲)。

這就是爲什麼你看到0x0.07fff00000001p-1022ny,這是一個十六進制浮點值0x0.07fff00000001p-1022其次是ny。也許你得到的非法指令錯誤是因爲你砸碎了堆棧中存儲的返回地址,所以當你的函數返回時,它跳轉到一個無效的地址。

作爲一個經驗法則,如果您使用printf函數之一,並且在格式字符串之後沒有指定至少一個可變參數,那麼您很可能會做錯某些事情。 fprintf中的含義是該函數的格式爲,但是當您沒有任何要格式化的內容時您正在使用它。所以這只是一個字符串副本,有一個額外的機會讓它錯誤。

如果你想使用printf系列函數的一個寫一個字符串,那麼你就可以避免意外指定的格式,你不是那個意思是這樣的:

sprintf(str1, "%s", SOME_STRING); 

,或者利用長 - 檢查:

#define STR1_SIZE 10 
char str1[STR1_SIZE]; 

if (snprintf(str1, STR1_SIZE, "%s", SOME_STRING) >= STR1_SIZE) { 
    // error-handling here 
} 

假如你不小心知道SOME_STRING適合你的緩衝區,那麼你可以省略錯誤處理和/或使用strcpy代替。但是當你這樣做的時候你看起來很愚蠢,而且長度錯了。

您還可以使用sizeof(str1)代替STR1_SIZE提供str1是一個數組(因爲它是在這裏),而不是一個指針(因爲它是在大多數字符串處理代碼)。

我試過轉義,即在sprintf中使用「\%any」而不是「%any」;但這並沒有幫助。

不錯的嘗試,沒有雪茄;-)

反斜線在一個字符串逃避特殊字符。由於%並不意味着字符串文字中的任何特殊內容,因此轉義它不起作用。由此產生的字符串是五個字符%,a,n,y,\0

稍後,您將該字符串傳遞給sprintf現在%有特殊含義,並有不同的轉義方式:%%

相關問題