栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

C:基于可以自动扩展缓冲区的stringbuffer,实现内存格式化输出(bufprintf)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C:基于可以自动扩展缓冲区的stringbuffer,实现内存格式化输出(bufprintf)

最近做一个C语言的嵌入式项目,需要分段向指定内存调用vsnprintf输出不定长度的格式化输出,因为是分段输出,而且长度不定,所以一开始就不能分配固定长度内存,每次输出都要从输出到上次的结尾开始,所以还要记录每次的输出长度。还是Java开发方便,有现成的StringBuffer可以用,不停的向StringBuffer调用 append添加就好了,哪有这么麻烦。
为了解决这个麻烦,我参照Java中的StringBuffer对象,实现了一个 stringbuffer,并基于它实现bufprintf函数可以向stringbuffer格式化输出,调用时就不需要再考虑自动分配内存和偏移量的问题了。

以下是可以直接运行的完整代码:
stringbuffer_test.c

#include 
#include 
#include 
#include 
#include 
#include 
#include 


typedef struct 
{
	
	char *buffer;
	
	size_t length;
	
	size_t offset;
} stringbuffer;

/
		return NULL;
	}

	if (needed > INT_MAX)
	{
		
		return NULL;
	}

	needed += p->offset + 1;
	if (needed <= p->length)
	{
		
		return p->buffer + p->offset;
	}

	
	if (needed > (INT_MAX / 2))
	{
		
		if (needed <= INT_MAX)
		{
			newsize = INT_MAX;
		}
		else
		{
			return NULL;
		}
	}
	else
	{
		
		newsize = ((needed + 256 - 1) >> 8 << 8);
	}

	
	newbuffer = (char*)realloc(p->buffer, newsize);
	if (newbuffer == NULL)
	{
		free(p->buffer);
		p->length = 0;
		p->buffer = NULL;

		return NULL;
	}

	p->length = newsize;
	p->buffer = newbuffer;
	return newbuffer + p->offset;
}
/
	va_list args;

	
	va_start(args, fmt);
	
	size_t bufsz = pbuf->length - pbuf->offset;
	int wsz = vsnprintf(pbuf->buffer + pbuf->offset, bufsz, fmt, args);
	va_end(args);
	if (wsz < 0)
	{
		
		if (errno == ERANGE)
		{
			
			va_list args1;
			va_start(args1, fmt);
			
			wsz = vsnprintf(NULL, 0, fmt, args1);
			char *output = ensure(pbuf, wsz);
			va_end(args1);
			if(!output)
			{
				
				printf("MEM ERRORn");
				return -1;
			}
			bufsz = pbuf->length - pbuf->offset;
			va_list args2;
			va_start(args2, fmt);
			wsz = vsnprintf(output, bufsz, fmt, args2);
			va_end(args2);
			assert(wsz < bufsz);
		}
		else {
			printf("vsnprintf ERROR %d:%s for fmt:[%s]n", errno, strerror(errno), fmt);
			return -1;
		}
	}
	else if (wsz >= bufsz)
	{
		
		
		char *output = ensure(pbuf, wsz);
		if(!output)
		{
			
			printf("MEM ERRORn");
			return -1;
		}
		bufsz = pbuf->length - pbuf->offset;
		va_list args;
		va_start(args, fmt);
		wsz = vsnprintf(output, bufsz, fmt, args);
		va_end(args);
		assert(wsz < bufsz);
	}
	pbuf->offset += wsz;
	return 0;
}
/
		printf("MEM ERRORn");
		return -1;
	}
	pbuf->buffer = (char*)p;
	pbuf->length = length;
	pbuf->offset = 0;
	return 0;
}
/


int main()
{
	stringbuffer sbuf;
	
	
	
	int c = stringbuffer_init(&sbuf, 0);
	if (c == 0)
	{
		bufprintf(&sbuf, "hello %sn", "jerry");
		
		bufprintf(&sbuf, "welcome to my partyn", "jerry");
		
		printf("sbuf content:n%sn", sbuf.buffer);
		
		
		
		
		stringbuffer_uninit(&sbuf, false);
	}
	else
	{
		printf("stringbuffer init failn");
	}
}

如果使用MSVC编译器,如在VS 开发人员提示(CMD)下执行 cl stringbuffer_test.c就可以直接编译出stringbuffer_test.exe,运行就能看到效果。

gcc下编译也很简单:

>gcc stringbuffer_test.c
>a.exe
sbuf content:
hello jerry
welcome to my party
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/572319.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号