C语言实现像高级语言一样的字符串操作
本帖最后由 乘简 于 2019-7-12 09:45 编辑如何用C语言操作字符串,像高级语言一样灵活的操作,字符串的长度任意变呢?答案是肯定的,而且更灵活,效率更高!
下面实现strcpy与strcat函数的结合体
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MEM_ALINE 64//预留量,为了减少内存分配次数
//定义结构体,声明变量的时候必须要赋初值
//比如string str={0,0,0};
typedef struct{
size_t memlen;//内存长度
size_t strlen;//字符长度
char* str;//字符串,后面有'\0'
}string;
//本模块所有的函数在变量不用时,都需要释放内存
void str_free(string *src)
{
if(src->memlen){//如果已经申请过了内存
src->memlen=src->strlen=0;
free(src->str);
}
}
//构建字符串,sour字符串在定义string t1={0,0,0};必须要初始化成0
//因为第二次要用realloc函数分配内存了
//本函数支持strcpy_free(&t1,t1.str,3);也就是说把自边往后移3位
//函数名后面加_free表示提醒程序员不要忘了用str_free函数释放内存
void strcpy_free(string *dest,char *sour,size_t start)
{
char *src=sour;//定义新变量,用于自身复制到自身时
size_t len=strlen(src)+1;//新字符的长度
if(start>dest->strlen)start=dest->strlen;//如果传入的起始位置大于原来的长度
if(len==1){//如果src="",可以直接用desc->str=0;与dest->strlen=start;来代替
if(dest->strlen){//原来有内容
dest->str=0;
dest->strlen=start;
}
}
else{
int isFree=0;//是否需要释放内存
if(dest->memlen==0){//如果第1次赋值
len+=start;//整长度加上起始位置
dest->strlen=len-1;//字符长度
dest->str=(char*)malloc(len);//分配内存
dest->memlen=len;//内存长度
strcpy(&dest->str,src);//复制字符串
}
else{
if(src>=dest->str && src<=dest->str+start){//内存地址有重叠,可能是自身复制到自身
src=(char*)malloc(len);//分配原来的长度
strcpy(src,sour);//先把原来的数据复制到临时变量中
isFree=1;//需要释放临时分配的内存
}
len+=start;//整长度加上起始位置
dest->strlen=len-1;//字符长度
if(dest->memlen<len){//内存扩容
len+=MEM_ALINE;//多分配预留量
dest->memlen=len;//内存长度
dest->str=(char*)realloc(dest->str,len);//扩容内存
}
strcpy(&dest->str,src);//复制字符串
}
if(len+(MEM_ALINE<<1)<=dest->memlen){//如果新内存空间,比原来小2倍预留量
dest->memlen=len+MEM_ALINE;//为了节省了内存空间,保留预留量后释放多余内存
dest->str=(char*)realloc(dest->str,dest->memlen);
}
if(isFree)free(src);//释放临时分配的内存
}
}
int main(int argc,char*argv[])
{
string t1={0,0,0};
//1.连接两个字符串
strcpy_free(&t1,"Hello! My Good ",0);
printf("%s\n",t1.str);
strcpy_free(&t1,"Friends.~~",t1.strlen);
printf("%s\n",t1.str);
strcpy_free(&t1,t1.str,7);
printf("%s\n",t1.str);
strcpy_free(&t1,"abcd",1);
printf("%s\n",t1.str);
str_free(&t1);//释放内存
}
支持楼主 代码我领走了,会好好对待它的,别担心 建议使用WINDOWS定义的ANSI_STRING结构体替代你自定义的结构体:typedef struct{
size_t memlen;//内存长度
size_t strlen;//字符长度
char* str;//字符串,后面有'\0'
}string;
typedef struct _ANSI_STRING {
USHORT Length; //字符串长度
USHORT MaximumLength; //内存长度
PCHARBuffer; //字符串指针,结尾不一定有\0,建议一律当作结尾没有\0
} ANSI_STRING; 本帖最后由 乘简 于 2019-6-26 17:33 编辑
美俪女神 发表于 2019-6-23 02:53
建议使用WINDOWS定义的ANSI_STRING结构体替代你自定义的结构体:
不想名字太长,,麻烦,而且USHORT太短了,,,而且结尾没有'\0'的话,肯定要另外写一套内存结构,配套的函数,而不是string结构,这样不管是结尾还是中间,都允许有'\0',string就是结尾带'\0'的。 本帖最后由 Ayala 于 2019-6-26 21:43 编辑
用字典或者字符组 这样就可以交叉引用字符串了
另外吐槽下 c语言不是高级语言么 一般来说用c语言 使用strcat的情况不算多 感觉用的最多的地方还是传递参数,索引全路径等 如果只是打印到内存 文件或者控制台这样做就有点造轮子了 Ayala 发表于 2019-6-26 21:32
用字典或者字符组 这样就可以交叉引用字符串了
另外吐槽下 c语言不是高级语言么 一般来说用c语言 使用strca ...
完全不是这样的,如果你自己要用纯C写一个表格控件的话,,呵呵。。。
每个单元格中的文本,是变长的,我想,高级语言,在低层也是这样实现的吧。。。 USHORT能到65535,塞一篇小文章都够了。
此外建议UNICODE_STRING,微软有相关函数。
以wcsncat函数举例,对应有RtlAppendUnicodeStringToString。
wcsncpy就能对应RtlCopyUnicodeString。
wcsn(i)cmp对应RtlCompareUnicodeString。
这些在ntdll.dll里都导出了。
甚至还能RtlUnicodeStringPrintf,实现swnprintf的操作。
如果知道这个结构体的指针,还能用%wZ把字符串给printf出来。
所以你真的是在过度造轮。 tangptr@126.com 发表于 2019-6-27 11:12
USHORT能到65535,塞一篇小文章都够了。
此外建议UNICODE_STRING,微软有相关函数。
以wcsncat函数举例,对 ...
USHORT肯定是不够的,万一有一些奇葩的功能需要用到超过65535时,就不好了,所以一劳永逸啊。。。
还有,unicode_string其实也是可以用char *来保存的。
而且这个与ntdll.dll中的那些函数完全无关,只是想用C实现像高级语言那样的不定长字符串合并运算的功能而已。 乘简 发表于 2019-6-27 10:52
完全不是这样的,如果你自己要用纯C写一个表格控件的话,,呵呵。。。
每个单元格中的文本,是变长的, ...
大多使用utf或者unicode_string格式 而且也不是所谓的不定长(有最大长度限制的) 对于长文本也不是直接储存的文本指针 大多时候是储存句柄 本帖最后由 Ayala 于 2019-6-29 11:22 编辑
乘简 发表于 2019-6-27 10:52
完全不是这样的,如果你自己要用纯C写一个表格控件的话,,呵呵。。。
每个单元格中的文本,是变长的, ...
表格控件使用xml样式处理不定长要好些 文本内容基本上不需要连续 不过用c语言编程很自由 每个人都有自己的开发习惯 可能自己写的代码今天觉得好 明天自己看着都难受 美俪女神 发表于 2019-6-23 02:53
建议使用WINDOWS定义的ANSI_STRING结构体替代你自定义的结构体:
我觉得他的这个似乎更好,只是string这个类型名和C艹的stl的string重名了,写成库的话会让调用者骂娘。
好在访问快并且使用了标准类型。USHORT什么的在我看来是魔鬼
XML看到就烦,还不如JSON简单直接。。。
关于这个,不考虑一下NBT嘛?来和我一起解析mca文件,编写新的地图画工具吧
页:
[1]