将数组中的字符附加到char指针

时间:2014-07-15 03:45:39

标签: c string

好的,所以我是那些经常写Java / C ++的人,而我刚刚开始编写C.我目前正在写一个词法分析器,我不能因为我不能执行字符串运算,所以我认为字符串在C中是如何工作的。所以这是我的问题:

char* buffer = "";
char* line = "hello, world";

int i;
for (i = 0; i < strlen(line); i++) {
    buffer += line[i];
}

我怎样才能在C中这样做?由于上面的代码不是有效的C,我该怎么做呢? 基本上我通过字符串line循环,我试图将每个字符附加到buffer字符串。

6 个答案:

答案 0 :(得分:2)

首先,缓冲区需要具有或超过复制到其中的数据的长度。

char a[length], b[] = "string";

然后将字符复制到缓冲区。

int i = 0;
while (i < length && b[i] != '\0') { a[i] = b[i]; i++; }
a[i] = '\0';

如果需要,可以反转顺序,只需在两个字符串中的最小长度值处启动i,然后递减值而不是递增。您也可以像其他人所建议的那样使用堆,纵向指向length的任意值或更改值。此外,您可以使用指针更改代码段(并让您更好地了解正在发生的事情):

int i = 0;
char *j = a, *k = b;
while (j - a < length && *k) { *(j++) =  *(k++); }
*j = '\0';

确保查找memcpy;并且不要忘记null终结符(oops)。

答案 1 :(得分:1)

字符串文字在C中是不可变的。修改一个会导致未定义的行为

如果您使用足以容纳角色的char 数组(您的缓冲区),您仍然可以修改其内容:

#include <stdio.h>

int main(void) {


    char * line = "hello, world";
    char buffer[32]; // ok, this array is big enough for our operation

    int i;
    for (i = 0; i < strlen(line) + 1; i++) 
    {
        buffer[i] = line[i];
    }

    printf("buffer : %s", buffer);

    return 0;
}

答案 2 :(得分:0)

#include <string.h>

//...

char *line = "hello, world";
char *buffer = ( char * ) malloc( strlen( line ) + 1 );

strcpy( buffer, line );

虽然在C字符串文字中有非const数组的类型,但最好用字符串文字用限定符const声明初始化指针:

const char *line = "hello, world";

C / C ++中的字符串文字是不可变的。

如果你想附加字符,那么代码可以按以下方式查找(行的每个字符都附加到循环中的缓冲区)

#include <string.h>

//...

char *line = "hello, world";
char *buffer = ( char * ) malloc( strlen( line ) + 1 );

buffer[0] = '\0';
char *p = Buffer;

for ( size_t i = 0; i < strlen( line ); i++ )
{
    *p++ = line[i];
    *p = '\0';
}

一般方法是,您发现指向终止零的指针替代目标字符使指针前进,并将新的终止零作为appenf。源缓冲区应足够大,以容纳一个字符。

答案 3 :(得分:0)

如果你想将一个字符附加到堆上分配的字符串,这是一种方法:

size_t length = strlen(buffer);
char *newbuffer = realloc(buffer, length + 2);
if (newbuffer) {  // realloc succeeded
  buffer = newbuffer;
  buffer[length] = newcharacter;
  buffer[length + 1] = '\0';
}
else {  // realloc failed
  // TODO handle error...
  free(buffer);  // for example
}

但是,这在循环中重复执行效率很低,因为您将(基本上)在同一个字符串上重复调用strlen(),并且每次重新分配缓冲区以适应另一个字符。 / p>

如果你想更聪明地重新分配,请跟踪缓冲区当前分配的容量,与其中的字符串长度分开 - 如果您了解C ++,请考虑{{1}之间的差异} object&#34; s&#34; size&#34;及其能力&#34; - 当需要重新分配时,将缓冲区的大小乘以缩放因子(例如加倍)而不是加1,这样重新分配的数量就是O(log n)而不是O( n)中。

这是一个好的字符串类在C ++中会做的事情。在C中,您可能希望将此缓冲区管理内容移动到其自己的模块中。

答案 4 :(得分:0)

缺乏任何背景的最简单的解决方案是:

char buffer[ strlen(line) + 1 ];
strcpy(buffer, line);

您可能习惯使用Java中的所有指针(因为Java中的非基本类型实际上更像是共享指针而不是其他任何东西)。但是,你不必在C中这样做,如果你这样做会很痛苦。

根据你的背景,也许一个好主意是在C中使用一个计数字符串对象,其中字符串对象拥有其数据。写struct my_string { char *data; size_t length; }。编写用于创建,销毁,复制和所需的任何其他操作的函数,例如附加字符或检查长度。 (与实现分开的接口!)对此的一个有用的补充是使它分配比length多1个字节,这样你就可以有一个null终止的函数,并允许它传递给一个期望的函数只读C风格的字符串。

这里唯一真正的缺陷是记住在进行复制操作时调用函数,而不是允许结构赋值发生。 (当然,您可以使用结构分配进行移动操作!)

答案 5 :(得分:0)

asprintf函数对于构建字符串非常有用,并且可用于基于GNU的系统(Linux)或大多数基于* BSD的系统。你可以这样做:

char *buffer;
if (asprintf(&buffer, "%s: adding some stuff %d - %s", str1, number, str2) < 0) {
    fprintf(stderr, "Oops -- out of memory\n");
    exit(1); }
printf("created the string \"%s\"\n", buffer);
free(buffer);  /* done with it */