【问题标题】:Array of pointers to pointers: managing strings for different languages指针数组:管理不同语言的字符串
【发布时间】:2018-02-14 14:48:16
【问题描述】:

我目前有很多字符数组存储简单的英文字符串以供显示。我也有指向这些字符数组的指针。

char helloAr[20] = "Hello";
char timeAr[20] = "Time";
char dogAr[20] = "Dog";

char* helloPtr = helloAr;
char* timePtr = timeAr;
char* dogPtr = dogAr;

我正在添加更多不同语言的字符数组,首先是法语。

char helloArFr[20] = "Bonjour";
char timeArFr[20] = "temps";
char dogArFr[20] = "chien";

如果用户选择法语,我计划更改所有指针(当前指向英语字符数组)指向的地址,因此它们现在指向法语字符数组。我假设我可以简单地为这些指针分配一个新值来执行此操作,

helloPtr = helloArFr;
timePtr = timeArFr;
dogPtr = dogArFr; 

但是我的实际代码会有很多数组,所以我想使用循环来执行此操作,而不是像上面那样使用大量语句。

为此,我计划创建一个指向我的字符数组地址的字符指针数组。

char* charArrAddresses [NUMBER_OF_TEXT_ARRAYS]=
{
    &helloAr,
    &timeAr,
    &dogAr,
    &helloArFr,
    &timeArFr,
    &dogArFr,
};

我还计划将所有指针存储在一个数组中,以便在我的单个语句中通过它们在数组中的位置来引用它们,但这是我需要一些帮助的地方,因为我不确定如何执行此操作。大概是这样的吧?

char ** langPtrs[NUMBER_OF_LANG_POINTERS]=
{
    helloPtr,
    timePtr,
    dogPtr,
};

在循环内的单个语句中,我将使用所选语言和 char 数组的数量来计算 charArrAddresses 的正确索引,现在我们称之为 X。我将使用循环的值(比如i)来索引我的langPtrs 数组。所以在我的单曲中想说的话,

for(i = 0; i<NUMBER_OF_LANG_POINTERS; i++)
{
    langPtrs[i]= charArrAddresses[X];
}

我正在尝试将存储在charArrAddresses 的索引X 中的字符数组的地址分配给langPtrs 数组中索引i 中的指针。我只需要关于如何声明 langPtrs 数组以及如何编写上面的单个语句的帮助。

【问题讨论】:

  • 首先选择语言,如果选择c++,则使用std::string
  • 我假设@user463035818 的意思是您应该选择一种编程语言。 c 和 c++ 是非常不同的语言,尽管有明显的相似之处。我不认为他的意思是你应该选择一种语言。由于问题是关于多语言支持的,我认为区分这一点可能很重要。
  • ... 是的,当然,错过了可能的误解。感谢您为支持多种语言所做的努力,但在编写代码时,您最好选择一种编程语言
  • 使用 std::vector<:string>> 可能更简单,然后当您需要访问数据时,唯一改变的就是向量。 (每个向量对应一种语言)
  • 感谢 cmets,我正在编写由其他人编写的代码,因此我被束缚在使用 char 字符串和 char 字符串指针、char 字符串及其指针以及一些指向这些指针的其他指针数组在很多地方(类、方法、显示/打印函数等)绑定到代码中,我无法更改它的工作方式。我只是想使用那里的东西并实现上面的例子。有人知道我如何用上面的想法解决我的问题吗?如何正确声明 langPtrs 数组以及如何在上面编写我的单个语句?

标签: c++ c arrays pointers


【解决方案1】:

不要将所有语言的字符串放在一个数组中,而是创建一个字符串和语言的二维数组。如果您不打算修改这些字符串中的任何一个,则可以将它们设为字符串文字而不是数组。

enum langs {
    LANG_ENGLISH,
    LANG_FRENCH,
    NUMBER_OF_LANGS
};

enum strings{
    STR_HELLO,
    STR_TIME,
    STR_DOG,
    NUMBER_OF_STRINGS
};

const char *langPtrs[NUMBER_OF_LANGS][NUMBER_OF_STRINGS]=
{
    { "Hello", "Time", "Dog" }
    { "Bonjour", "temps", "chien" }
};

由于enum 中的符号值从 0 开始并为每个后续符号递增 1,因此您可以将它们用作数组索引。每个enum的最后一个成员,不对应数组中的实际元素,可以作为数组的大小。

因此,例如,如果您想用法语打印“时间”字符串,您可以使用:

printf("%s\n", langPtrs[LANG_FRENCH][STR_TIME]);

如果您想始终从“当前”语言打印字符串,您可以为当前语言创建指向子数组的指针:

const char **currentLang = langPtrs[LANG_FRENCH];

然后你可以使用它:

printf("%s\n", currentLang[STR_TIME]);

编辑:

如果你想保留helloPtrtimePtrdogPtr,并且你想根据当前语言设置它们,你可以把它们的地址放在另一个数组中:

const char **usedInClassesPtrs[NUMBER_OF_STRINGS] = {
    &helloPtr,
    &timePtr,
    &dogPtr
}

然后循环遍历数组,解引用每个元素,为您提供要更改的实际指针,并根据当前语言从二维语言数组中为它们分配一个字符串,如下所示:

for (i=0; i<NUMBER_OF_STRINGS; i++) {
    *usedInClassesPtrs[i] = langPtrs[currentLang][i];
}

【讨论】:

  • 如果是 C++,并且您真的希望指针直接引用字符串文字,那么您将不得不将 const 放在那里。在 C 语言中可能也不是一个糟糕的主意?
  • @LightnessRacesinOrbit 不错。固定。
  • 不错。但是我倾向于像这样开始这样的枚举:enum langs {INVALID_LANGUAGE = -1, LANG_ENGLISH, ...
  • 嗨 dbush,感谢您的评论,我实际上已经在使用枚举作为索引,正如您在我的代码中的许多其他地方所建议的那样,喜欢 2D 数组的想法,它实际上是一些东西我打算从一开始就研究它,但我完全忘记了,也感谢您提供的示例代码,我将 100% 尝试使用实现它。我的主要问题是我正在处理由其他人编写的代码,因此我被束缚在使用 char 字符串和 char 字符串指针、char 字符串及其指针,以及指向这些指针的其他一些指针数组( 1 of 2)
  • 在很多地方(类、方法、显示/打印函数等)都与代码相关联,改变它的工作方式将是一场噩梦(尽管我一定会在阅读您的答案后尝试) .如果由于对字符串当前存储方式的大量依赖而无法更改代码,您是否知道我如何用上面的想法解决我的问题?如何正确声明 langPtrs 数组以及如何在上面写下我的单一陈述? (2 之 2)
【解决方案2】:

@debush 的答案应该很好用。 从您的示例中,我假设您的代码中一次只有一种语言处于活动状态。为此,我建议使用资源方法来管理您的多语言支持。你基本上可以加载一种语言的相应资源文件,并将其存储在std::vector&lt;std::string&gt;std::map&lt;const enum/id/etc., std::string&gt;或任何类似的数据结构中。这可以根据您的需要即时或在初始化阶段完成。在您的代码中,您保存指向此数据结构std::vector&lt;std::string&gt;* ptr 的指针,以通过调用(*ptr)[index] 来引用当前加载的语言。

【讨论】:

    猜你喜欢
    • 2022-09-23
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 2014-09-29
    • 1970-01-01
    • 2021-06-28
    • 2014-11-29
    相关资源
    最近更新 更多