2012-01-30 61 views
3

我在這裏建立了一個基於4個參數的字符串,並用system()調用它,但是看起來有點亂。有沒有更正確的方法,我應該做到這一點,而不是使用所有這些strcat和str1-4?建立字符串的方法c

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

int main(int argc, char *argv[]) 
{ 

    char str1[40] = "sed -n 's/.*\\("; 
    char str2[] = "\\)\\(.*\\)\\("; 
    char str3[] = "\\).*/\\2/p' "; 
    char str4[] = " > "; 

    if (argc != 5) 
    { 
     fprintf (stderr, "Usage %s <LogFile> <token1> <token2> <DumpFile>\n", 
       argv[0]); 
       exit(EXIT_FAILURE); 
    } 

    strcat(str1, argv[2]); 
    strcat(str1, str2); 
    strcat(str1, argv[3]); 
    strcat(str1, str3); 
    strcat(str1, argv[1]); 
    strcat(str1, str4); 
    strcat(str1, argv[4]); 

    system(str1); 

    return 0; 
} 

回答

8

你的代碼的一個問題是你沒有檢查適合40個字節的參數。

我可能會使用snprintf

snprintf(str, LENGTH, "sed -n 's/.*\\(%s...", argv[2]...); 
+0

你指的是哪個標準?它是C標準的當前版本(C2011)和以前版本(C99)的標準版本。唯一不符合標準的地方是微軟在Timewarp中被卡住的Windows,並堅持認爲只有C89是標準的,並且在下劃線後面隱藏了最近的名字:'_snprintf()'等。 – 2012-01-30 19:55:25

+0

@JonathanLeffler出於某種原因,它沒有在C99中指定的想法。我明白了。真棒! – cnicutar 2012-01-30 19:56:36

2

總是有sprintf這會讓你的生活變得更簡單。確保你使用sptrintf緩衝區足夠大的結果。還有一個更安全的版本snprintf這將爲你做邊界檢查。

2

唯一的問題是,你可能會得到緩衝區溢出(如果輸入太長)。要修復它,請檢查字符串的長度(使用strlen),並分配足夠的內存以包含所需的字符串。

在分配了足夠的內存之後,您可以使用循環,或者讓sprintf爲您完成工作。

2

str1只有40字節長,並要追加太多的數據吧。堆棧溢出可能發生。我會做:

char buffer[1000]; // Choose a reasonable size 
snprintf(buffer, sizeof(buffer), 
    "sed -n 's/.*\\(%s\\)\\(.*\\)\\(%s\\).*/\\2/p' %s > %s", 
    argv[2], argv[3], argv[1], argv[4]); 
3

這樣可以節省重複strcat()的二次行爲。 OTOH,如果你打電話給system(),那麼它會丟失。

char str1[4096]; 
char str0[] = "sed -n 's/.*\\("; 

sprintf(str1, "%s%s%s%s%s%s%s%s", str0, argv[2], str2, argv[3], str3, argv[1], str4, argv[4]); 

如果你擔心緩衝區溢出,您可以使用snprintf()(你應該是40個字節str1是不夠的,你離開了96關結束後,在char str1[4096];)。您可以檢查返回值以查看寫入了多少個字符。

+0

「你離開96端」單獨值得+1。 :-) – ruakh 2012-01-30 20:26:31

1

如果你想要你的代碼處理任意長的參數,那麼你將需要動態地分配字符緩衝區malloc

  1. 創建一個局部變量來計算所需的總長度,並使用重複調用strlen來計算該長度。
  2. 請致電malloc記住爲空終止符添加一個字符。
  3. 多次使用strcpystrcat來建立字符串。
  4. 致電system
  5. 致電free(或者如果您的流程即將終止,請勿打擾)。