我如何收集字符到一个字符串在C?



我需要为我的词法分析器收集一些字符到缓冲区中,但我不知道如何。我在stackoverflow上读过一些答案,但那是不同的情况。我有一个while循环,它读取下一个字符,我想在其中添加逻辑,这样它就可以将新字符附加到内存缓冲区中。

// init buffer with the first char 'h'
char *buffer = malloc(sizeof(char));
buffer[0] = 'h';
buffer[1] = '';
// go through input char by char
while(...)
{
char c = read_next_char(); 
buffer.append(c) // I whould do in JavaScript, but not in C :(
}

在您的情况下,您在开始分配单个字节的char *buffer = malloc(sizeof(char));,并访问缓冲区[1]或任何其他索引是UB。

你可以在开始分配一个已知的字节数,直到你看到一个需要更多缓冲区大小的点。

像这样,

int buffersize = 100;
int index =0;
char *buffer = malloc(sizeof(char)*buffersize); //100bytes are allocated
if(!buffer)
return;
buffer[index++] = 'h';
buffer[index++] = '';
// go through input char by char
while(...)
{
char c = read_next_char(); 
if(index == buffersize ){
buffersize +=100;
buffer= realloc(buffer, buffersize );
//here buffer size is increased by 100
if(!buffer) 
return;
}

buffer[index++] = c ;
}

注意:必须在使用结束后释放buffer,否则会导致资源泄漏。

您需要简单地覆盖null终止字符并添加新字符。

char *append(char *buff, int ch)
{
size_t len = strlen(buff);
buff[len] = ch;
buff[len+1] = 0;
return buff;
}

代码假设buff是一个有效的指针,指向足够长的内存块,可以容纳新的char和null终止char。它必须包含一个有效的C字符串。

与java或javascript不同,C中没有字符串类型,您需要自己编写。

这是一个非常简单的例子,说明如何高效地构建字符串。

这是不言自明的。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct DynamicString
{
char* string;    // pointer to string
int length;      // string length
int capacity;    // capacity of the string buffer (= allocated size)
};
#define DS_CHUNKSIZE 100   // we increase the buffer size by DS_CHUNKSIZE
// change this as needed
// Initialize the structure
void InitDynamicString(struct DynamicString* ds)
{
ds->capacity = DS_CHUNKSIZE + 1;
ds->string = malloc(ds->capacity);
ds->string[0] = 0;   // null terminator
ds->length = 0;      // initial string length 0
};
// Increase the string buffer size if necessary
// (internal function)
void IncreaseSize(struct DynamicString* ds, int newsize)
{
if (ds->length + newsize + 1 > ds->capacity)
{
ds->capacity = ds->length + newsize + DS_CHUNKSIZE + 1;
ds->string = realloc(ds->string, ds->capacity); // reallocate a new larger buffer
}
}
// append a single character
void AppendChar(struct DynamicString* ds, char ch)
{
IncreaseSize(ds, sizeof(char)); // increase size by 1 if necessary
ds->string[ds->length++] = ch;  // append char
ds->string[ds->length] = 0;     // null terminator
}
// append a string
void AppendString(struct DynamicString* ds, const char *str)
{
IncreaseSize(ds, strlen(str));  // increase by length of string if necessary
strcat(ds->string, str);        // concatenate
ds->length += strlen(str);      // update string length
}

int main(int argc, char* argv[])
{
struct DynamicString ds;
InitDynamicString(&ds);   // initialize ds
AppendChar(&ds, 'a');     // append chars
AppendChar(&ds, 'b');
AppendChar(&ds, 'c');
AppendString(&ds, "DE");      // append strings
AppendString(&ds, "xyz1234");
printf("string = "%s"", ds.string);  // show result
}

你的代码可以这样使用:

struct DynamicString buffer;
InitDynamicString(&buffer)
dAppendChar(&buffer, 'h');
while(...)
{
char c = read_next_char(); 
AppendChar(&buffer, c); // quite similar to  buffer.append(c)
}

免责声明:

  • 代码没有经过彻底的测试,可能存在bug。
  • 没有任何错误检查。mallocrealloc可能失效
  • 需要编写SetString(struct DynamicString *ds, const char *string)等其他有用的函数
  • 有优化的空间,特别是strcat可以不同的处理,阅读这篇文章了解更多信息。我把这个(非常简单的)练习留给读者。

在C语言中没有标准函数可以在字符串后面添加字符。您需要从头开始编写代码。

我们从这里开始:

char *buffer = malloc(sizeof(char));  // This allocates memory for ONE char
buffer[0] = 'h';                      // So this is fine
buffer[1] = '';                     // but this is bad. It writes outside the allocated memory

通过为两个字符分配内存来修复它

char *buffer = malloc(2);  // sizeof(char) is always 1 so no need for it
buffer[0] = 'h';
buffer[1] = '';

当您想要在字符串中添加一个新字符时,您还需要为它分配内存。换句话说,您需要增加buffer所指向的内存的大小。为此,可以使用realloc函数。

size_t buffer_size = 2;
char *buffer = malloc(buffer_size );
buffer[0] = 'h';
buffer[1] = '';
while(...)
{
char c = read_next_char(); 
char* tmp = realloc(buffer, buffer_size + 1);
if (tmp == NULL)
{
// realloc failed ! Add error handling here
... error handling ...
}
buffer = tmp;
buffer[buffer_size - 1] = c;  // Add the new char
buffer[buffer_size] = '';     // Add the string termination
++buffer_size;                  // Update buffer size
}

其他答案也可以,但它们很复杂。我建议一个更简单的解决方案。字符串是一个char的数组,其中该字符串的最后一个char''字节。在它之后的数组中可以有更多的char,但它们不是字符串的一部分。

更简单的解决方案是创建一个足够大的数组,98%的情况下,使用它来存储字符串,当字符串变得太长,你可以退出一个错误。在需要的时候改变缓冲区的大小是一个很好的特性,但是当你是C语言的新手时,你不应该从这里开始。

#define BUFFER_SIZE 1024
// init buffer with the first char 'h'
char buffer[BUFFER_SIZE];
buffer[0] = 'h';
buffer[1] = '';
// go through input char by char Replace the ... with your condition of the while loop
for(size_t i=1;...;i++) //start at 1 so the 'h' is not overwritten
{
if(i==BUFFER_SIZE-1) //-1 for the ''-Byte
{
fputs("Input too long, exitn",stderr);
exit(1);
}
//Are you sure you don't need error handling for read_next_char()?
buffer[i] = read_next_char();
buffer[i+1]=''; //End the string with a ''-Byte
}

相关内容

  • 没有找到相关文章

最新更新