【问题标题】:Why does streaming a char pointer to cout not print an address?为什么将 char 指针流式传输到 cout 不打印地址?
【发布时间】:2012-06-07 19:50:49
【问题描述】:

当我使用printf() 打印一个字符指针时,它会根据 %u 或 %s 使用转换说明符来决定是打印地址还是打印整个字符串。

但是当我想用cout 做同样的事情时,cout 将如何决定应该在地址和整个字符串之间打印什么?这是一个示例来源:

int main()
{
  char ch='a';
  char *cptr=&ch;
  cout<<cptr<<endl;
  return 0;
}

这里,在我的 GNU 编译器中,cout 正在尝试将 ch 输出为字符串。

如何使用cout通过cptr获取ch的地址?

【问题讨论】:

标签: c++ string pointers char cout


【解决方案1】:

重载分辨率选择ostream&amp; operator&lt;&lt;(ostream&amp; o, const char *c); 用于打印C 风格的字符串。您希望选择另一个 ostream&amp; operator&lt;&lt;(ostream&amp; o, const void *p);。您可能最好在此处使用演员表:

 cout << static_cast<void *>(cptr) << endl;

【讨论】:

  • static_cast&lt;void*&gt; 在这种情况下应该足够了,因为我们谈论的是基本数据类型指针。
【解决方案2】:

cout 如果收到char *,则打印一个字符串,就这么简单。

这是operator &lt;&lt; 的重载ostream

ostream& operator<< (bool val);
ostream& operator<< (short val);
ostream& operator<< (unsigned short val);
ostream& operator<< (int val);
ostream& operator<< (unsigned int val);
ostream& operator<< (long val);
ostream& operator<< (unsigned long val);
ostream& operator<< (float val);
ostream& operator<< (double val);
ostream& operator<< (long double val);
ostream& operator<< (const void* val);

ostream& operator<< (streambuf* sb);

ostream& operator<< (ostream& ( *pf )(ostream&));
ostream& operator<< (ios& ( *pf )(ios&));
ostream& operator<< (ios_base& ( *pf )(ios_base&));

ostream& operator<< (ostream& out, char c );
ostream& operator<< (ostream& out, signed char c );
ostream& operator<< (ostream& out, unsigned char c );


//this is called
ostream& operator<< (ostream& out, const char* s );
ostream& operator<< (ostream& out, const signed char* s );
ostream& operator<< (ostream& out, const unsigned char* s );

如果你想要地址,你想要:

ostream& operator<< (const void* val);

所以你需要转换为const void*

【讨论】:

    【解决方案3】:

    我只是将其转换为 void*,因此它不会尝试将其解释为 C 字符串:

    cout << (void*) cptr << endl;
    

    但是,更安全的选择是在 dirkgently 的回答中使用 static_cast(这样至少在编译时检查了转换)。

    【讨论】:

    • c 风格的演员表?使用 c++ cast 不是更安全吗?
    • @AdrienPlisson 它不如 reinterpret_cast 以外的 C++ 强制转换安全。在这种微不足道的情况下,我不会打扰 C++ 风格的演员表,尽管我想为了完整性,我应该提一下。很难预见到 void* 只是为了找出它最终会有害的情况,尽管我敢肯定,一旦代码库变得足够大,可能会发生一些非常奇怪的转换。
    • @Corbin:对于void *,C++11 的reinterpret_cast 还可以。见Issue #1120
    • @dirkgently 啊,不知道。
    【解决方案4】:

    正如 Luchian 所说,cout 根据类型知道要打印什么。如果要打印指针值,则应将指针转换为 void* ,它将作为指针插入。

    【讨论】:

      猜你喜欢
      • 2014-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 2021-07-07
      • 1970-01-01
      相关资源
      最近更新 更多