【问题标题】:This simple(?) C++ string declaration issue appears to have defeated StackExchange? [closed]这个简单的(?)C++ 字符串声明问题似乎打败了 StackExchange? [关闭]
【发布时间】:2016-07-08 13:13:30
【问题描述】:

Edit3:我打算回到这个来简化问题,并遍历重复出现相同答案的响应列表,以解释为什么它们不起作用。

编辑:解释为什么这个问题是独一无二的:这个问题的其他答案都没有回答这个问题。这个问题没有答案。基本上我能表达出来:

  1. 有一个 const string = "Hello";
  2. 如何在编译时获取字符串长度?

Edit2:我在这里再次问了这个问题,因为我被各种不起作用的解决方案所淹没。我对重复解释为什么它们不起作用感到筋疲力尽。唯一有效的答案正是我来这里寻找更好的方法之前的答案。

我无法改变的基本情况是这样的:

我有一个字符串声明(这是强制要求的):

const string LETTERS = "Random Sentence";

接下来,我需要对字符串执行一系列单独的操作。

所以,我正在尝试声明第二个可变字符串作为这些操作结果的容器:

例如字符串 ALPHABETICISED[15];

但是,这是不明智的。如果这是一个很长的程序并且我更改了候选字母,那么我一定不要忘记手动将 15 更改为新值。如果有几种情况,很容易发生事故。

我想做的是这样的:

int size = (int)LETTERS.length();
string alphabeticised[size];

但这是无效的,原因有两个:

  1. 它会创建一个字符串数组,但不会设置一个字符串的长度。
  2. 无论如何它不会在编译时求值,所以当我尝试编译它时它会抛出一个非常量表达式错误,因为它还没有替换值。

一些建议使用 constexpr,这会有所帮助,但它必须针对 MSVC 2012 进行编译,这基本上将我限制为 c++98 约定。无论如何,我不能在 MSVC 2012 中使用 constexpr。

此外,出于类似的原因,我想在将对字符串进行操作的循环中使用此大小,例如:

for ( int x = 0; x < LETTERS.length(); x++ ) {
    // Do stuff, for random example:
    incremented[x] = ++LETTERS[x];
}

不过,我:不应该:需要在运行时找到 LETTERS.length!我已经知道每次会是什么。

那么,我如何在编译时发现和使用字符串长度,这样我就不必在运行时找到它了?

注意事项:

该解决方案必须针对 MSVC 2012 进行编译,该版本大致符合 c++98 标准,并且 C++11 功能非常少,甚至没有 constexpr。

此外,我无法访问调试器,因此我无法确定编译器是否已将 LETTERS.Length() 替换为常量表达式。

简而言之,如何针对 MSVC 2012 在编译时声明一个与已知长度的常量字符串长度相同的新字符串?

看起来很简单!人们必须一直这样做吗?为非可变数组上的操作结果分配一些易失性内存?

【问题讨论】:

  • 我看不到与 StackExchange 的关系。
  • @GeorginaDavenport 因为他们不知道您要做什么。因为你的问题完全没有意义。
  • @ForceBru 不,请停止。 OP已经够糊涂了。
  • @GeorginaDavenport,您无法理解有关您拥有的类型的一些概念(这可能是投票关闭的原因),您正在驳斥社区正在解释的内容而不做任何基础研究来理解为什么你不能做你想做的事。 All I want is a method to find that known string length at compile time 而这在 C++ 中是不可能的,而恰好是 const string LETTERS = "Random Sentence"; ..
  • 为什么你需要在编译时知道长度?

标签: c++ string constants declaration


【解决方案1】:

我没有发现任何问题?

string incremented = LETTERS;  // modifiable string of exactly the same length as LETTERS
// or
string incremented(LETTERS.length(), 0);
for ( int x = 0; x < LETTERS.length(); x++ ) {
    // Do stuff, for random example:
    incremented[x] = LETTERS[x] + 1;
}

即使在 MSVC 2008 中也可以编译。

如果您对可修改字符串分配在堆上这一事实感到困扰,请考虑原始 LETTERS 字符串也分配在堆上(并将 C 文字复制到分配的内存中)。除非实现了小字符串优化并且原始字符串的内存分配在堆栈上(在这种情况下,第二个可修改字符串的内存也将分配在堆栈上)。

要在不预先初始化任何内容的情况下进行分配,您也可以这样做:

string incremented;
incremented.reserve(LETTERS.length());
for ( int x = 0; x < LETTERS.length(); x++ ) {
    // Do stuff, for random example:
    incremented += LETTERS[x] + 1;
}

【讨论】:

  • 是的,实际上这就是我在发布问题之前开始的方式。我唯一的问题是它将 const 字符串分配给可变字符串。这就是我拒绝它的原因。我一开始就是这样做的,然后来到这里,因为新字符串只需要旧字符串的长度,而不需要实际内容。有没有办法在没有内容的情况下分配大小?
  • @GeorginaDavenport 是的,你被展示了如何做到这一点in a previous question of yours
  • 你一直在重复同样的事情 ForceBeu:我在分配字符串大小时没有任何问题,问题是找到已经分配的 const 字符串的长度。它是在寻找我需要做的长度,而不是分配它。
  • 我没有使用这个字符串递增(LETTERS.length(), 0);我不需要它。我正在使用这个:string incremented = LETTERS;这就是我从这个答案中使用的全部内容,这与我在第一次问之前已经拥有的内容相同。来到这里的全部目的是找到一种只分配大小的更好方法。
猜你喜欢
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多