如何在 C++ 中的字符串之间使用 cin?
Posted
技术标签:
【中文标题】如何在 C++ 中的字符串之间使用 cin?【英文标题】:How do I use cin between strings in C++? 【发布时间】:2015-12-14 23:32:43 【问题描述】:我对 C++ 还很陌生,并且一直在学习这样的东西:
cout << "My age is: ";
cin >> age;
与 cin 混在一起,我遇到了一个障碍。
假设我想写“我 x 岁!”。
"x" 是 cin >> 年龄;
我是这样写代码的。
cout << "I am ";
cin >> age;
cout << "years old!";
障碍在于这会产生换行符。
我不想换行。
我怎样才能让所有这些都留在一条线上?
【问题讨论】:
这对我来说没有多大意义。你不应该先要求用户输入年龄,然后整体输出std::cout << "I am " << x << " years old.\n"
吗?
那么,您是否想提出一些类似空白的东西,用户可以在其中输入他们的年龄?如果是这样,不幸的是,这不是基于文本的系统通常的工作方式,但我确信这可以通过 ncurses 完成,尽管它会变得更加复杂。
在没有换行符的情况下输入内容的方法是关闭流上的缓冲。但这取决于您使用的操作系统,而不是 C++ 的一部分。例如,在 Windows 中,您可以获取字符而根本不将它们回显到屏幕上,然后再决定将哪些字符放在屏幕上。
###有可能!如果您使用 Microsoft Visual Studio,因此可以使用标头 conio.h
,那么有一个解决方案(但这可能有点棘手,因为您需要处理字符,而不是流)。看看this answer to similar question on Stack Overflow。 PS:得到你需要的字符后,你可以回去使用流从中读出一个整数值。
#Numeri 指出我想做什么。用 cin 填空。 #DietmarKuhl 解释说这是可能的,但需要一些工作。我意识到,据我所知,我仅限于使用 #Olipro 呈现的 cin 逻辑。
【参考方案1】:
我假设您实际上希望输入与最终输出一致。否则,解决方案是微不足道的:首先读取值然后打印它,例如:
std::cout << "how old are you? ";
std::cin >> x;
std::cout << "I am " << x << " years old\n";
处理与输出一致的输入有点棘手。这里的问题是控制台处理实际上是由系统完成的,而不是由语言完成的。因此,输入数据时需要等待换行符。换行符将由控制台处理并创建换行符。要禁用此行为,有必要依赖控制台行为来解决问题。没有标准的 C++ 方法可以这样做。
我不知道如何处理 Windows 上的控制台控件:我主要是 UNIX 程序员。在 UNIX 系统上,您可以使用 tcgetattr()
和 tcsetattr()
将输入模式设置为非规范(即,清除 ICANON
位)。所需的文件描述符只是标准输入的一个,即0
。
一旦控制台使用非规范模式,所有按键都会立即转发到应用程序,并且不会完成屏幕回显。因此,读取函数实际上需要回显单个字符,然后转发到解析函数。最简单的方法是创建一个过滤流缓冲区,它在转发字符时为std::cin
到std::cout
进行必要的回显。但是,将所有这些放在一起有点工作......
在制作演示时,我注意到我还需要处理回显(当用户使用回车键时避免换行)。重置控制台标志也很重要,因为即使在程序终止后它们中的一些实际上仍然保持更改。将这些位放在一起但仍然缺乏错误处理的实现可能如下所示:
#include <iostream>
#include <ctype.h>
#include <termios.h>
struct non_canon_buf
: std::streambuf
char buffer;
non_canon_buf()
termios flags = ;
tcgetattr(0, &flags);
flags.c_lflag &= ~(ICANON | ECHO);
tcsetattr(0, TCSANOW, &flags);
~non_canon_buf()
termios flags = ;
tcgetattr(0, &flags);
flags.c_lflag |= ICANON | ECHO;
tcsetattr(0, TCSANOW, &flags);
int underflow()
if (std::cin.get(buffer))
this->setg(&buffer, &buffer, &buffer + 1);
if (!std::isspace(static_cast<unsigned char>(buffer)))
std::cout << buffer << std::flush;
return std::char_traits<char>::to_int_type(buffer);
return std::char_traits<char>::eof();
;
int main()
non_canon_buf sbuf;
std::istream in(&sbuf);
std::cout << "I am ";
int age = 0;
in >> age;
std::cout << " years old\n";
if (!in)
std::cout << "ERROR: failed to enter a valid age!\n";
【讨论】:
为了完整起见,Windows 等效项将是SetConsoleMode
并禁用 ENABLE_LINE_INPUT
和 ENABLE_ECHO_INPUT
。然后可以使用ReadConsole
(或ReadFile
with stdin)。
@Mawg 虽然这可能不是权威来源,但cppreference.com 有一个关于std::endl
的注释,上面写着“使用 std::endl 代替 '\n',一些消息来源鼓励,可能会显着降低输出性能。”所以\n
可能就是这样。
@Mawg: \n
是完全有效的 C++。您可能更喜欢std::endl
,但您不应该向使用您不喜欢的编码约定的任何答案发送 Stack Overflow cmets 垃圾邮件。另外,请注意 \n
和 std::endl
在技术上甚至不做完全相同的事情,正如 Alex 的链接中所解释的那样。
同意;他们不做同样的事情。这就是为什么应该使用std::endl
。在特定情况下,当您确切地知道自己想要做什么时,\n
是可以接受的,但在这里我们试图教新手良好的编码实践。
@Mawg:有趣的是你会说我应该使用std::endl
。但是请注意,我对'\n'
的使用是经过深思熟虑的。出于某种原因,您可能想看看blog 我几年前写的一个恐惧。特别是,我强烈反对认为新来者应该使用std::endl
的观点:没有人应该使用std::endl
永远是正确的评估。【参考方案2】:
cin
在控制台输入换行符后读取输入。
因此,您可以连续执行此操作的唯一方法是提示用户他们的年龄,然后继续编写它。
例如:
std::cout << "Enter your age> ";
std::cin >> age;
std::cout << "I am " << age << " years old" << std::endl;
【讨论】:
你能参考一下换行之后的东西吗?【参考方案3】:unsigned int age;
std::cin >> age;
std::cout << "I am " << age << " years old!" << std::endl;
【讨论】:
这只是避免这个问题的方法,不是解决方案。 加一个是唯一使用std::endl
而不是\n
的人
@Mawg This one 也使用 std::endl
...【参考方案4】:
你不能在纯 C++ 中做你想做的事。您可以按照其他人的建议进行并重新打印该行:
std::cout << "I am " << age << " years old!\n"
或者您可以使用特定于操作系统的功能来清除控制台输出。 Read about this here.
例如,对于 Windows,您可以使用 system("cls");
,在询问用户年龄后清除控制台。
#include <stdlib.h>
int main(int argc, char* argv[])
unsigned int age;
std::cout << "My age is: "
std::cin >> age;
system("cls");
std::cout << "I am " << age << " years old!\n"
...
产量:
C:>AgeProgram.exe I am 10 years old
【讨论】:
@Mawgstd::endl
刷新cout
缓冲区。在极少数情况下,你真的想要这个。 "\n"
和 endl
在其他方面都是相同的。 Read this.【参考方案5】:
你可以这样做
int user_age;
std:cout<<"Enter Your Age:" //Ask user for age
std::cin >>user_age; //Read user input
std::cout<<"I am"<<user_age<<"years old!"<< std::endl; //finlly display the value
【讨论】:
以上是关于如何在 C++ 中的字符串之间使用 cin?的主要内容,如果未能解决你的问题,请参考以下文章