鱼C论坛

 找回密码
 立即注册
查看: 1807|回复: 3

[技术交流] 自动扩容版 gets

[复制链接]
发表于 2020-8-14 18:54:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<malloc.h>



  4. #ifndef DEFAULT_STRING_LENGTH
  5. #define DEFAULT_STRING_LENGTH 50 //默认长度 50
  6. #endif



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


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


  18.         if (_Str) {//分配成功
  19.             *_Capacity = DEFAULT_STRING_LENGTH;
  20.         }
  21.         else {//分配失败
  22.             return NULL;
  23.         }
  24.     }
  25.     else if (!_Str) {//传入空指针
  26.         _Str = (char*)malloc(*_Capacity * sizeof(char));//分配* _Capacity 长度的空间

  27.         if (!_Str) {//分配失败
  28.             *_Capacity = 0;
  29.             return NULL;
  30.         }
  31.     }


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

  41.                 case '\0':
  42.                     *_Capacity = _Len;
  43.                     return (char*)realloc(_Str, *_Capacity * sizeof(char));
  44.             }

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


  61.     return NULL;//装饰
  62. }



  63. //自动扩容版的 gets
  64. char* autoalloc_gets(char* _Str, size_t* const _Capacity) {
  65.     return autoalloc_fgets(_Str, _Capacity, stdin);//直接调用 autoalloc_fgets
  66. }
复制代码

评分

参与人数 1荣誉 +3 鱼币 +3 贡献 +3 收起 理由
zltzlt + 3 + 3 + 3 鱼C有你更精彩^_^

查看全部评分

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-14 20:38:18 | 显示全部楼层
谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-8-15 15:33:19 | 显示全部楼层
重新开辟内存空间,再把原来的内容复制过怎么样?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-8-19 16:29:46 | 显示全部楼层
Cool_Breeze 发表于 2020-8-15 15:33
重新开辟内存空间,再把原来的内容复制过怎么样?

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-9 08:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表