C ++:只打印一个char

时间:2010-06-02 13:03:09

标签: c++ pointers char iostream

当我从char*读取一个std::cin并且我想将其写入std::cout时,它会打印,直到它在内存中找到\0为止。那是做了什么:

char c;
cin >> c;
char* pChar = &c;
pChar++;
*pChar = '\0';
println(&c); // My own method: void println(char * str) { cout << str << endl; }

但我认为这不是一个安全的行动。

有更安全的方法吗?

6 个答案:

答案 0 :(得分:3)

简单地:

char c;
cin >> c;
cout << c;

答案 1 :(得分:2)

当你想要打印一个角色时,正确的做法是打印那个角色:

char ch;
if(std::cin >>ch) 
  std::cout << ch;
else
  // handle input error

如果你出于某种原因想要在每个角色背后留下换行符,那么就这样做:

std::cout << char << '\n';

注意:您还会看到std::endl用于输出换行符,但std::endl执行两项操作:输出'\n'刷新输出缓冲区 。虽然后者在输出到控制台时不是问题(它仍然比人类能够读取它更快),但由于使用std::endl,我看到应用程序变慢(在文件输出上)而不是'\n'。因此,您最好从一开始就要注意是否需要刷新缓冲区。


请注意,您正在做的事情

pChar++;
*pChar = '\0';

你正在调用可怕的未定义的行为:使用pChar++,您将指针递增到指向变量后面(这很好),而*pChar = ...则是{{1}}写入你的变量背后的任何记忆。
在实践中,这可能会破坏您的堆栈,希望在下一刻使您的应用程序崩溃。然而,从理论上讲,这会调用未定义的行为,根据C ++标准,它可能会执行任何操作(包括经常引用它可能会格式化磁盘)。
请勿写入您不拥有的内存。
对于初学者来说, 很难获得正确的指针,所以只要你能尽可能地避开它们。您可以使用C ++做很多事情而无需手动摆弄指针。

答案 2 :(得分:2)

已经有一些关于如何做你想做的事情的答案,但我想解释你的代码中那些pchar++下面究竟是什么以及为什么它是邪恶的。

C风格的施法赋予了灵活性,但允许你在脚下射击自己。你已经在堆栈上分配了char c(这意味着你为它保留了确切的内存量,它等于sizeof(char),这是1字节。

然后你取一个你变量的记忆地址(没关系),这样你就可以将char变量和 指针 带到这个{ {1}}位于。但是你的下一步是完全邪恶的,因为你(在做char时)实际上正在破坏堆栈。

正如我之前所说,编译器为char内存保留了一个字节,但是你所做的意思是显式遍历内存中的下一个字节(甚至可能属于其他程序的堆栈)并用自己的值重写它。

此行为也可以通过以下示例进行描述:

认为您必须更改硬盘上某个具体文件(*(pchar + 1) = 0)的内容。您是否认为可以重写顺序关注a.file的文件内容,例如,增加a.file的大小?

答案 3 :(得分:1)

char c;
cin >> c;
char pChar[2] = {0};
pChar[0] = c;;
println(pChar); 

或者如果你想要更像C ++,重载函数:

void println( const char * s ) {
   cout << s << endl;
}

void println( char  c ) {
   cout << c << endl;
}

甚至模板:

template <typename T >
void println( T t ) {
   cout << t << endl;
}

答案 4 :(得分:0)

打印您输入的字符:

char c = 0;
std::cin >> c;
std::cout << c;

获取字符串中的字符并获取第一个字符:

char c = 0;
std::cin >> c;
std::string str;
str += c;

std::cout << str.at(0) << std::endl;

修改

或许你问过这件事? :

std::string str;
std::cin >> str;

std::cout << str;

我不确定究竟是什么问题。

答案 5 :(得分:0)

char c;
std::cin >> c;
if (std::cin) {
    std::cout << c << std::flush;
}

该代码打印“只有一个字符”。 std::cout << c << std::endl打印两个:c'\n'

如果您愿意,也可以使用println功能:

char str[2] = {'\0', '\0'};
std::cin >> str[0];
if (std::cin) {
    println(str);
}

请注意,if (std::cin)会导致编译器调用std::iosstd::istream类的operator void*() const成员,std::cin扩展,以便将{{1}}评估为{{1}}布尔值。