2012-01-30 60 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(或者如果您的流程即将终止,请勿打扰)。