gpt4 book ai didi

c - 在没有显式字符串复制的情况下,char 字符串和 wchar_t 字符串之间的函数逻辑重用?

转载 作者:太空宇宙 更新时间:2023-11-04 02:00:45 26 4
gpt4 key购买 nike

我正在用 C 编写一个数据结构来存储命令;这是我不满意的来源:

#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>

#include "dbg.h"
#include "commandtree.h"

struct BranchList
{
CommandTree *tree;
BranchList *next;
};

struct CommandTree
{
wchar_t id; // wchar support actually has no memory cost due to the
bool term; // padding that would otherwise exist, and may in fact be
BranchList *list; // marginally faster to access due to its alignable size.
};

static inline BranchList *BranchList_create(void)
{
return calloc(1, sizeof(BranchList));
}

inline CommandTree *CommandTree_create(void)
{
return calloc(1, sizeof(CommandTree));
}

int CommandTree_putnw(CommandTree *t, const wchar_t *s, size_t n)
{
for(BranchList **p = &t->list;;)
{
if(!*p)
{

*p = BranchList_create();
if(errno == ENOMEM) return 1;
(*p)->tree = CommandTree_create();
if(errno == ENOMEM) return 1;
(*p)->tree->id = *s;
}
else if(*s != (*p)->tree->id)
{
p = &(*p)->next;
continue;
}
if(n == 1)
{
(*p)->tree->term = 1;
return 0;
}
p = &(*p)->tree->list;
s++;
n--;

}
}
int CommandTree_putn(CommandTree *t, const char *s, size_t n)
{
wchar_t *passto = malloc(n * sizeof(wchar_t));
mbstowcs(passto, s, n);
int ret = CommandTree_putnw(t, passto, n);
free(passto);
return ret;
}

这工作得很好,但我对我处理树支持 wchar_t 的方式相当不满意。当我意识到 CommandTree 的填充会使任何小于 7 字节的数据类型消耗同样多的内存时,我决定添加它,但为了不重复代码,我有 CommandTree_putn 重用支持 wchar_t 的 CommandTree_putnw 中的逻辑。

但是,由于charwchar_t的大小不同,我不能只传递数组;我必须使用 mbstowcs 进行转换,并将一个临时的 wchar_t * 传递给 CommandTree_putnw。这是次优的,因为 CommandTree_putn 将看到最多的使用情况,这会使内存使用量增加五倍(sizeof (char)sizeof (char) + sizeof ( wchar_t)) 存储的字符串,如果其中很多要用较长的命令实例化,它可能会堆叠。

我想知道我可以做一些事情,比如创建第三个包含逻辑的函数,并传递一个 size_t,这取决于它将传递给它的字符串转换为void *const char *const wchar_t * 但是考虑到 C 是静态类型的,我几乎必须复制将 s 转换为各自类型的逻辑,这会破坏我想要的“单一逻辑实例”的想法。

所以最终的问题是,我能否仅提供一次程序逻辑并分别传递包装器 const char *const wchar_t *,而不创建临时的 wchar_t * 在函数中处理 const char *?

最佳答案

我不知道您的硬性要求,但是正是因为这个问题,wchar_t 往往很难使用;很难与使用 char 的现有代码相结合。

我使用过的所有代码库最终都迁移到了 UTF-8,这消除了以不同类型存储字符串的必要性。 UTF-8 使用标准的 strcpy/strlen 类型的字符串操作函数,并且完全支持 Unicode。唯一的挑战是您需要将其转换为 UTF-16 以调用 Windows Unicode API。 (OS X 可以直接使用 UTF-8。)你没有提到平台,所以我不知道这对你来说是否是个问题。在我们的例子中,我们只是编写了采用 UTF-8 字符串的 Win32 包装器。

你会用C++吗?如果是这样,并且实际类型 wchar_t 很重要(而不是 Unicode 支持),您可以模板化函数,然后使用 std::wstringstd 实例化它们::string 取决于字符串宽度。如果你够勇敢,你也可以将它们写成基于 charwchar_t,但是你需要编写特殊的包装函数来处理像 strcpy 这样的基本操作wcscpy 相比,到目前为止,它的整体工作量更大。

在纯 C 中,我认为根本没有 Elixir 。有一些令人讨厌的答案,但没有一个我可以板着脸推荐。

关于c - 在没有显式字符串复制的情况下,char 字符串和 wchar_t 字符串之间的函数逻辑重用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27513531/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com