2011-03-05 99 views
1

我正在处理一个输入字符串,它包含一个进程名称,后跟任意数量的参数。连接多个字符串?

我需要一个字符串中的进程名称以及所有参数。 我以为我可以在一个循环中使用strcat,以便循环遍历所有的参数,并且每次都将arg附加到字符串,但是我在获取空的字符串以开始循环时遇到问题。

任何人都可以帮助我一些基本的代码?

谢谢。

编辑: 我发布我的代码为清晰。小李的职位是最接近我现在有:

char * temp; 
    strcpy(temp,""); 
    for (i = 4; i < argc-1; i++) // last arg is null, so we need argc-1 
    { 
     strcat(temp,argv[i]); 
     strcat(temp," "); 
    } 

在我的for循环的时刻(神奇的数字,我知道) 我得到这个代码段错误忽略4。是因为我的字符串分配?我认为是这样,因此我问了如何组合字符串的问题。

+1

我想你将需要分配一个缓冲区的地方。首先进入随机缓冲区的strcpy需要很多运气才能工作! – 2011-03-05 19:42:55

+0

如果你可以把它形成一个答案,我会给你复选标记。因为这就是我所需要的,是一个温度第一的malloc。谢谢! – Blackbinary 2011-03-05 19:48:54

+0

我已经更新了我的答案。我没有包含很多代码,因为我认为你基本上知道你在做什么,不需要为你写的代码! – 2011-03-05 19:54:26

回答

1

你想要一个空的C字符串?这是你在找什么:char p[] = "";


UPDATE

后您发布一些代码,很显然,你已经忘记了分配缓冲temp。只需首先运行参数,计算所需的长度(使用strlen),然后分配temp。不要忘记零终结者的空间!

0

你可以提供“的参数的任意量”作为一个参数,即一个阵列/列表中,然后执行该伪代码:

str = ""; 
i = 0; 
while i < length of input 
{ 
str = strcat (str , input[i]); 
i++; 
} 
0

在C A字符串由字符数组被终止表示通过一个“空”字符,其值为0的'\ 0'。这让所有字符串函数知道字符串的末尾在哪里。下面是对声明一个空字符串的不同方式的探索,以及它们的含义。

得到一个空字符串的常用方法是

char* emptyString = ""; 

不过,现在emptyString指向字符串文字,无法进行修改。如果你想在你的循环中连接一个空字符串,你必须在初始化时将它声明为一个数组。

char buffer[] = ""; 

这给你一个大小的数组。即buffer[0]是0.但是你想要一个数组连接到它必须足够大以适应字符串。所以,如果你有一定大小的字符串缓冲区,可以初始化它是空的,像这样:

char buffer[256] = ""; 

串在buffer现在是“空字符串”。它包含的内容是buffer[0]是0,缓冲区的其余条目可能是垃圾,但是一旦连接了其他字符串,这些内容就会被填充。

不幸的是,C的问题是,你永远不会有一个“无限”的字符串,在那里你可以安全地连接在一起,你从知道它从一开始就是确定的大小。如果你的参数数组也是字符串,你可以使用strlen找到它们的长度。这给你一个字符串的长度,没有空字符。一旦你知道了所有子字符串的长度,你现在就会知道你的最终缓冲区会有多长。

int totalSize; // assume this holds the size of your final concatenated string 
// Allocate enough memory for the string. the +1 is for the null terminator 
char* buffer = malloc(sizeof(char) * (totalSize + 1)); 
buffer[0] = 0; // The string is now seen as empty. 

在此之后,您可以使用strcat自由连接字符串。

+2

这是一个非常不规范的方式来获得一个空的C字符串。 – 2011-03-05 19:37:00

+0

@David Heffernan我想我已经超越了我自己。我添加了一些澄清。 – 2011-03-05 20:15:21

0
#include<stdio.h> 
    #include<stdarg.h> 

    int main(int argc, char** argv) { 
      // the main parameters are the same situation you described 
      // calling this program with main.exe asdf 123 fdsa, the program prints out: asdf123fdsa 

      int lengths[argc]; 
      int sum =0; 
      int i; 
      for(i=1; i<argc; i++) { // starting with 1 because first arg is program-path 
        int len = strlen(argv[i]); 
        lengths[i] = len; 
        sum+=len; 
      } 
      char* all = malloc(sum+1); 
      char* writer = all; 
      for(i=1; i<argc; i++) { 
        memcpy(writer, argv[i], lengths[i]); 
        writer+=lengths[i]; 
      } 
      *writer = '\0'; 
      printf("%s\n", all); 

      system("pause"); 
      return 0; 
    } 
+0

我觉得'int长度[argc];'不是标准的C,是吗? – Thomas 2011-03-05 19:41:52

+0

@Thomas是的,它只在C99中添加。 'malloc(sizeof(int)* argc)'将与旧的编译器兼容。 – 2011-03-05 19:48:17

+0

这将完成工作。难道它不仅仅是让你用真正的内置动态长度字符串对象来爱语言! – 2011-03-05 20:18:18

5

比方说,你输入的字符串是在char指针,暗示性地叫argv一个数组,长度argc的。

我们首先需要确定多少空间所需的输出:

int length = 0; 
for (int i = 0; i < argc; ++i) 
    length += strlen(argv[i]); 

然后我们将它分配,对于'\0'终止添加额外的char

char *output = (char*)malloc(length + 1); 

最后,级联:

char *dest = output; 
for (int i = 0; i < argc; ++i) { 
    char *src = argv[i]; 
    while (*src) 
     *dest++ = *src++; 
} 
*dest = '\0'; 

请注意,我没有在这里使用strcat。原因是,这使我们为Schlemiel the Painter's algorithm:对于每次迭代,整个输出字符串将被扫描以查找其结束,导致二次运行时间。

不要忘记释放输出字符串时,即可大功告成:

free(output); 

我有点累了,所以我在这里可以俯瞰东西。欢迎使用标准库函数的更好解决方案。如果strcat返回一个指向dest中的终止字节的指针,但这很方便。

+0

您也可以使用一系列的(n)printf调用,因为它们返回了写入的字符数。 – user470379 2011-03-05 20:21:17

+0

这应该比重量级的'printf'变种更简单。但你是对的,它确实有效。 – Thomas 2011-03-06 09:54:07