【问题标题】:Why does c_str() print the string twice?为什么 c_str() 打印字符串两次?
【发布时间】:2009-02-02 23:43:46
【问题描述】:

所以... 我去的时候:

cout<<stringName<<endl;

我明白了:

NT

但是当我去的时候:

cout<<stringName.c_str()<<endl;

我明白了:

NTNT

为什么?

【问题讨论】:

  • 你是否在使用 wstring。
  • 不知道那是什么。
  • 您是否在附近进行任何 fork() 操作 - 也许您有多个进程正在刷新或多或少相同的缓冲区。
  • 您的代码中还有其他错误。
  • @windfinder,请反馈。结果是什么?你找到错误了吗?

标签: c++ c-strings


【解决方案1】:

使用以下代码进行快速测试:

#include <string>
#include <iostream>

using namespace std;

int main(void) {
    string str = "NT";
    cout << str.c_str() << endl;
    return 0;
}

生成一个 NT 实例,因此看起来您可能在某处有另一个输出调用。

【讨论】:

  • 这怎么可能是原因?假设他仅将这一行从“stringName”更改为“stringName.c_str()”,则无法更改字符串的打印次数。另外,他打印了一个换行符,所以很明显不是这段代码的两个实例正在运行。
  • @Larry 没有迹象表明代码的其余部分是什么样的,或者在运行之间使用了相同的输入,因此它可能在某处有条件。也不能保证之前的调用也会包含 endl。我说“可能”是有原因的。
  • @Kevin 如果有“另一个输出调用”,它首先发生并且没有换行符。我从表面上看,他唯一改变的是那一行,而不是“其他”。无论哪种方式,所描述的行为变化都不仅仅由另一个“NT”打印命令的存在来解释。
  • @Larry 我同意你的观点,从表面上看可能暗示了一个更难诊断的问题,但在这种情况下,我的第一直觉是首先寻找最简单最明显的解决方案;尤其是在给出有限的细节和没有上下文的情况下。
【解决方案2】:

一个传统的 C 字符串(通过 char const* 访问)有一个以字符 0 结尾的字符序列。(不是数字 0,而是一个实际的零值,我们将其写为 '\0'。)没有明确的长度——所以各种字符串操作一次只读取一个字符,直到它到达'\0'

C++ std::string 在其结构中具有明确的长度。

您的字符串字符的内存布局是否可能如下所示:

'NTNT\0'

但是字符串的长度设置为2?

这将导致这种行为 — 直接操作 std::string 将表现为它只有两个字符长,但如果您使用 s.c_str() 执行传统 C 操作,它将看起来像 "NTNT"

我不确定什么恶作剧会让你进入这种状态,但它肯定会符合症状。

进入这种状态的一种方法是实际写入到字符串的字符,例如:strcat((char *)s.c_str(), "NT")

【讨论】:

  • 只有当 std::string::c_str() 有故障时才会出现这种行为。标准 (21.3.6[1]) 保证 c_str() 指向一个由 \0 终止的数组(不一定与内部使用的字符串存储相同)
  • @Steve,如果 c_str() 没有做任何事情并且数据已经以空终止的方式维护,则不会。然后,如果您通过直接使用 data() 操作来覆盖该空终止符,它可能会产生这个结果。
  • 一般来说,如果你对字符串对象做了任何无效的事情,结果是 c_str() 没有按照你的预期做,这并不意味着 c_str() 是错误的; -)
  • C 字符串不是char*。 C 字符串是char[N],也可能是const,您通常会传递指向它的指针。
  • -1:这个答案可以总结为“你得到“NTNT”。可能出了问题,比如你得到“NTNT”。这与症状相符。”
【解决方案3】:

显示更多代码。好像你做了cout &lt;&lt; ealier 却忘记了你做了。如果你做 cout&lt;&lt; "mofo" &lt;&lt; stringName.c_str()&lt;&lt; "|||" &lt;&lt; endl; 它会打印什么它说 NTmofoNT||| 吗?如果是这样,那很可能就是发生了什么;)

【讨论】:

    【解决方案4】:

    这不是c_str() 的问题,但可能与程序其余部分的其他异常有关。

    制作一个执行相同操作的“hello world”应用程序,您会发现它在那里运行良好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 1970-01-01
      • 1970-01-01
      • 2015-04-21
      相关资源
      最近更新 更多