C言語でStringBufferもどきを作成してみる

c言語は速いのはいいのですが、いかんせん標準ライブラリ群が貧弱な面は否めません。

文字列周りの処理だとC++のSTLあたりを使用すれば簡単ですが、純粋にCで簡単に作成してみました

  • string_buffer.h
#ifndef _STRING_BUFFER_H
#define _STRING_BUFFER_H
#include 

struct string_buffer {
	unsigned int item_size;
	char *item;
	unsigned int max_item_size; // 実際のメモリ確保量
};


extern struct string_buffer *create_string_buffer();
extern void delete_string_buffer(struct string_buffer *buf);
extern int append_string_buffer(struct string_buffer *buf, char *val, unsigned int val_len);


#endif
  • string_buffer.c
#include "string_buffer.h"
#define ITEM_SIZE 1024
struct string_buffer *create_string_buffer(){
				struct string_buffer *buf;
				buf=(struct string_buffer *)malloc(sizeof(struct string_buffer));
				if(buf==NULL)return NULL;
				buf->item=(char*)malloc(sizeof(char)*ITEM_SIZE);
				if(buf->item==NULL){
								free(buf);
								return NULL;
				}
				buf->item[0]='\0';
				buf->item_size=0;
				buf->max_item_size=ITEM_SIZE;
				return buf;
}
void delete_string_buffer(struct string_buffer *buf){
				if(buf!=NULL){
								if(buf->item!=NULL) free(buf->item);
								free(buf);
				}
}
int append_string_buffer(struct string_buffer *buf, char *val, unsigned int val_len){
				int size;
				char *newbuf;
				int diff=buf->max_item_size-buf->item_size;
				if(diff>val_len){
								strncat(buf->item,val,val_len);
								buf->item_size+=val_len;
				}else{
								size=buf->max_item_size+ITEM_SIZE;
								newbuf=(char*)malloc(sizeof(char)*size);
								if(newbuf==NULL) return -1;
								newbuf[0]='\0';
								strncpy(newbuf,buf->item,buf->item_size);
								free(buf->item);
								buf->item=newbuf;
								buf->max_item_size=size;
								return append_string_buffer(buf,val,val_len);
				}
				return 0;
}

実行してみます

  • main.c

static void print_string_buffer(char *header,struct string_buffer *buf){
				printf("%s:item_size=%d,char=%s,max_item_size=%d\n",header,buf->item_size,buf->item,buf->max_item_size);
}
int main(){
				struct string_buffer *buf;
				buf=create_string_buffer();
				if(buf==NULL)exit(0);

				append_string_buffer(buf,"test",sizeof("test"));
				print_string_buffer("1",buf);

				append_string_buffer(buf," 1111",sizeof(" 1111"));
				print_string_buffer("2",buf);

				append_string_buffer(buf,"",sizeof(""));
				print_string_buffer("3",buf);

				append_string_buffer(buf,"a",sizeof("a"));
				print_string_buffer("4",buf);

				append_string_buffer(buf,"12345678901234567890",12);
				print_string_buffer("5",buf);

				append_string_buffer(buf,"123",sizeof("123"));
				print_string_buffer("6",buf);
				delete_string_buffer(buf);
}
  • 実行結果
$ a.out
1:item_size=5,char=test,max_item_size=1024
2:item_size=11,char=test 1111,max_item_size=1024
3:item_size=12,char=test 1111,max_item_size=1024
4:item_size=14,char=test 1111a,max_item_size=1024
5:item_size=26,char=test 1111a123456789012,max_item_size=1024
6:item_size=30,char=test 1111a123456789012123,max_item_size=1024