永恒的蓝色梦想 发表于 2020-8-14 18:54:14

自动扩容版 gets

本帖最后由 永恒的蓝色梦想 于 2020-8-31 11:45 编辑

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>



#ifndef DEFAULT_STRING_LENGTH
#define DEFAULT_STRING_LENGTH 50 //默认长度 50
#endif



//自动扩容版的 fgets
char* autoalloc_fgets(char* _Str, size_t* const _Capacity, FILE* const _Stream) {
    /*
    警告:
      只能用于动态分配的数组,静态数组使用后果自负。
    */
    char* _Temp;
    size_t _Index = 0;


    //输入检查
    if (!*_Capacity) {//容量为 0
      _Str = (char*)malloc(DEFAULT_STRING_LENGTH * sizeof(char));//分配 DEFAULT_STRING_LENGTH 长度的空间


      if (_Str) {//分配成功
            *_Capacity = DEFAULT_STRING_LENGTH;
      }
      else {//分配失败
            return NULL;
      }
    }
    else if (!_Str) {//传入空指针
      _Str = (char*)malloc(*_Capacity * sizeof(char));//分配* _Capacity 长度的空间

      if (!_Str) {//分配失败
            *_Capacity = 0;
            return NULL;
      }
    }


#define _Len (_Index + 1)
    for (;;) {
      if (_Len < *_Capacity) {
      LABEL:
            switch (_Str = fgetc(_Stream)) {//遇到以下字符,终止扫描
                case '\n':
                case '\r':
                case EOF:
                  _Str = '\0';//'\0' 的话,就不需要重置了

                case '\0':
                  *_Capacity = _Len;
                  return (char*)realloc(_Str, *_Capacity * sizeof(char));
            }

            ++_Index;
      }
      else {//扩容,默认扩容为原来的两倍
            *_Capacity <<= 1;
            if (_Temp = (char*)realloc(_Str, *_Capacity * sizeof(char))) {//为了防止 realloc 返回 NULL 造成内存泄露
                _Str = _Temp;
                goto LABEL;//扩容完之后不需要重新判断,goto 提高效率
            }
            else {//扩容失败
                _Str = '\0';//放置字符串终止符
                *_Capacity >>= 1;//退回来
                return _Str;
            }
      }
    }
#undef _Len


    return NULL;//装饰
}



//自动扩容版的 gets
char* autoalloc_gets(char* _Str, size_t* const _Capacity) {
    return autoalloc_fgets(_Str, _Capacity, stdin);//直接调用 autoalloc_fgets
}

weiter 发表于 2020-8-14 20:38:18

谢谢{:10_278:}

Cool_Breeze 发表于 2020-8-15 15:33:19

重新开辟内存空间,再把原来的内容复制过怎么样?

永恒的蓝色梦想 发表于 2020-8-19 16:29:46

Cool_Breeze 发表于 2020-8-15 15:33
重新开辟内存空间,再把原来的内容复制过怎么样?

页: [1]
查看完整版本: 自动扩容版 gets