+ -
当前位置:首页 → 问答吧 → 写了一个连接字符串的lib, 请指点一二.

写了一个连接字符串的lib, 请指点一二.

时间:2010-08-02

来源:互联网

本帖最后由 liexusong 于 2010-08-02 11:42 编辑
  1. /*
  2. * FileName: mystring.c
  3. * eg. MyString *mystr = mystr_new(); mystr->add(mystr, "Hello World\n"); mystr->free(mystr);
  4. */

  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>

  8. #define INITSIZE 1024
  9. #define EXTSIZE  512

  10. struct _MyString;
  11. typedef struct _MyString MyString;

  12. struct _MyString {
  13.         unsigned long size;
  14.         unsigned long used;
  15.         char *pstr;
  16.         char *current;
  17.        
  18.         MyString *(*add)(MyString *, char *);
  19.         int (*free)(MyString *);
  20.         char *(*fetch)(MyString *);
  21. };

  22. MyString *mystr_add(MyString *ptr, char *str) {
  23.         size_t len, newsize;
  24.         char *tmp;
  25.        
  26.         if (!ptr) {
  27.                 return NULL;
  28.         }
  29.        
  30.         len = strlen(str);
  31.        
  32.         if (ptr->size - ptr->used >= len) {
  33.                 memcpy(ptr->current, str, len);
  34.                 ptr->current += len;
  35.                 ptr->used += len;
  36.         } else {
  37.                 newsize = (len / (ptr->size - ptr->used) + 1) * EXTSIZE + ptr->size; /* new malloc memory size */
  38.                 tmp = (char *) malloc ( newsize + 1 );
  39.                
  40.                 if (!tmp) {
  41.                         return NULL;
  42.                 }
  43.                
  44.                 memcpy(tmp, ptr->pstr, ptr->used);
  45.                 memcpy(tmp + ptr->used, str, len);
  46.                 tmp[newsize] = '\0';
  47.                
  48.                 free(ptr->pstr);
  49.                
  50.                 ptr->size = newsize;
  51.                 ptr->used += len;
  52.                 ptr->pstr = tmp;
  53.                 ptr->current = ptr->pstr + ptr->used;
  54.         }
  55.        
  56.         return ptr;
  57. }

  58. int mystr_free(MyString *ptr) {
  59.         if (!ptr) {
  60.                 return -1;
  61.         }
  62.        
  63.         free(ptr->pstr);
  64.         free(ptr);
  65.        
  66.         return 0;
  67. }

  68. char *mystr_fetch(MyString *ptr) {
  69.         if (!ptr) {
  70.                 return NULL;
  71.         }
  72.        
  73.         *(ptr->current) = '\0';
  74.         return ptr->pstr;
  75. }

  76. MyString *mystr_new() {
  77.         MyString *ptr;
  78.         ptr = (MyString *) malloc (sizeof (MyString));
  79.         if (!ptr) {
  80.                 return NULL;
  81.         }
  82.        
  83.         ptr->pstr = (char *) malloc (INITSIZE + 1);
  84.         if (!ptr->pstr) {
  85.                 return NULL;
  86.         }
  87.        
  88.         ptr->pstr[INITSIZE] = '\0';
  89.         ptr->size = INITSIZE;
  90.         ptr->used = 0;
  91.         ptr->current = ptr->pstr;
  92.        
  93.         ptr->add = mystr_add;
  94.         ptr->free = mystr_free;
  95.         ptr->fetch = mystr_fetch;
  96.        
  97.         return ptr;
  98. }

  99. int main() {
  100.         MyString *mystr;
  101.         mystr = mystr_new();
  102.        
  103.         mystr->add(mystr, "The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to calloc, malloc, or realloc.\n");
  104.         mystr->add(mystr, " The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument. realloc does not zero newly allocated memory in the case of buffer growth.\n");
  105.         mystr->add(mystr, "realloccalls mallocin order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when realloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call\n");
  106.        
  107.         printf("%s", mystr->fetch(mystr));
  108.         printf("\nMemory size: %d Bytes, used: %d Bytes\n", mystr->size, mystr->used);
  109.        
  110.         mystr->free(mystr);
  111.         return 0;
  112. }
复制代码
不知道效率怎么样呢?

作者: liexusong   发布时间: 2010-08-02

请高手指点一下吧!

作者: liexusong   发布时间: 2010-08-02

自己写的目的是啥?

作者: hellioncu   发布时间: 2010-08-02

回复 hellioncu


    请问有现成的吗? 我也不想自己写的.

作者: liexusong   发布时间: 2010-08-02

现成的就是char *啦。。

你这样写也没啥问题的,效率虽然没有增强,至少应该不会影响
s

作者: 雨过白鹭洲   发布时间: 2010-08-02

很OO 哦

作者: peidright   发布时间: 2010-08-02

你不就是想写个strcat吗

作者: rune_zhang   发布时间: 2010-08-02

原来是C的呀,前面没仔细看,以为是C++。

*(ptr->current) = '\0';为啥要放在fetch而不是add中呢?
add时为啥不用realloc?

MyString *mystr;不能定义成结构只能用指针比较麻烦

作者: hellioncu   发布时间: 2010-08-02

参与glibc去吧,我不混那个社区,不知道啥情况。

作者: prolj   发布时间: 2010-08-02

定义自己的字符串也没什么不好,比如加上长度信息,这样就不用非得\0结束字符串。。

作者: 雨过白鹭洲   发布时间: 2010-08-02

回复 雨过白鹭洲

效率有增强的。  memcpy vs strcpy。

作者: OwnWaterloo   发布时间: 2010-08-02

谢谢大家的回答, 另外realloc比malloc好在哪里呢?

作者: liexusong   发布时间: 2010-08-02

相关阅读 更多