当我从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; }
但我认为这不是一个安全的行动。
有更安全的方法吗?
答案 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::ios
类std::istream
类的operator void*() const
成员,std::cin
扩展,以便将{{1}}评估为{{1}}布尔值。