#include <algorithm>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
bool running = true;
while(running == true)
{
string input;
cout << "[Enter 'exit' to exit the program]\n";
cout << "Enter the text you want to reverse: ";
getline(cin, input);
if (input.compare("exit") == 0)
{
running = false;
break;
}
reverse(input.begin(), input.end());
cout << "The reversed version of your text is: " << input << endl << endl;
}
return 0;
}
#1 楼
不要using namespace std;
因为可能发生名称冲突,这被认为是不好的做法,...尽管没有人会伤害您,因为这是一个很小的程序:)
< br请勿将布尔值与布尔值进行比较
完全不需要
running == true
之类的东西,因为running
本身已经是一个条件。只需使用running
即可。不需要
running
不需要变量
running
。您需要一个用于嵌套循环(要同时突破),但对于单个循环,最好使用单个break
和无限循环。为什么要使用
compare
?看到
input.compare("exit") == 0
会让我直接进入文档,因为我不知道compare
的返回值是什么。if (input == "exit");
更清楚。
不要连续刷新2次(或根本不刷新)
std::endl
打印新行,然后刷新stdout
。这会导致性能下降,因此最好输出实际的换行符。在您的情况下:std::cout << something << "\n\n";
请注意,在某些平台上(或如果需要),必须冲洗蒸汽才能看到输出。在这种情况下,最好显式并使用
std::flush
。您没有使用命令行参数
那么为什么要命名它们呢?您可以省略名称,或定义不带任何参数的
main
:int main(int, char**) {} //1)
int main() {} //2)
我更喜欢选项2。
您的代码使用实现特定行为
在
std::string
标头中定义了string
。并非每个编译器都包括带有string
或iostream
的algorithm
(VS不包括),因此您必须显式包括它。不要依赖自动包含。从技术上讲,您不需要
return 0;
仅对于
main
,如果省略return 0;
,编译器会添加它对您而言,因此从技术上讲,您无需指定它。评论
\ $ \ begingroup \ $
要点:行为是特定于实现的,而不是“定义实现”;后者是标准中的术语,需要编译器来记录其行为。
\ $ \ endgroup \ $
–贝克特(Pete Becker)
16-09-23在12:45
\ $ \ begingroup \ $
当C ++标准说某事是“实现定义的”时,这意味着一个合格的实现必须记录它的工作。对于头文件,允许C ++实现将其他#include指令放入头文件(与C头不同)。因此,当您#include
\ $ \ endgroup \ $
–贝克特(Pete Becker)
16-09-23在19:22
\ $ \ begingroup \ $
“不要使用命名空间std;”为什么不?该建议仅对头文件(或打算包含的文件)有效。 “不要将布尔值与布尔值进行比较”那么您希望将它们与之进行比较?也许您的意思是常量,例如true / false。
\ $ \ endgroup \ $
–luk32
16-09-24在14:24
\ $ \ begingroup \ $
@ luk32不是。在源文件中仍然可能发生名称冲突。它还包括许多通用名称,字符串,列表,向量,for_each等,因此不可用。是的,我是那个意思。
\ $ \ endgroup \ $
–Rakete1111
16-09-24在14:26
\ $ \ begingroup \ $
@ luk32我看不到以std ::前缀所有内容如何损害可读性。如果一个类定义了一个反向函数,并且使用了命名空间std;在源文件的顶部,您将获得模糊的功能。但是可以,有时候由于编码风格而没有必要(例如,每个函数都以大写字母开头)。
\ $ \ endgroup \ $
–Rakete1111
16-09-24在14:38
#2 楼
除了以前的答案:输入后还应检查流状态(例如,用户可以按Ctrl + Z并输入,或者可以到达输入文件的末尾)。
return 0;
函数中不需要main
。您也可以将此代码移至该函数,然后将
break;
替换为return;
我的版本:
#include <iostream>
#include <string>
#include <algorithm>
int main(int argc, char** argv)
{
using std::cout;
using std::endl;
while (true)
{
std::string input;
cout << "[Enter 'exit' to exit the program]\n";
cout << "Enter the text you want to reverse: ";
if (!getline(std::cin, input) || input.compare("exit") == 0)
break;
std::reverse(input.begin(), input.end());
cout << "The reversed version of your text is: " << input << endl << endl;
}
}
#3 楼
一个小小的nitpick,在下面的代码中:string input;
cout << "[Enter 'exit' to exit the program]\n";
cout << "Enter the text you want to reverse: ";
getline(cin, input);
我会将字符串输入向下移到getline(...)中使用它的位置旁边:
cout << "[Enter 'exit' to exit the program]\n";
cout << "Enter the text you want to reverse: ";
string input;
getline(cin, input);
仅有助于将通用代码保持在一起。在像这样的一个小例子中,很容易找借口,但是说在字符串输入和getline之间有20条或更多的语句。读者必须记住输入是在阅读其他不相关的语句时定义的。
很小,但是有些东西要记在脑海中。
#4 楼
删除“类型退出退出”的东西。如果有人想撤消“退出”→“提示”怎么办?只需使用结束程序的标准^ C(Control-C)。您甚至不需要执行任何操作。如果有人想退出,则只需按Control-C。最终版本:
#include <algorithm>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
while(true)
{
string input;
cout << "Enter the text you want to reverse: ";
getline(cin, input);
reverse(input.begin(), input.end());
cout << "The reversed version of your text is: " << input << endl << endl;
}
return 0;
}
评论
\ $ \ begingroup \ $
使用SIGINT可能是结束程序的标准(尽管我从未见过如此命名),但是通常您必须处理该信号,否则您将不做任何清理就退出。而且,它是特定于实现的,即POSIX。不确定Windows上的应用程序如何处理Control-C。最好只说“输入文本<...>或按Enter退出”。
\ $ \ endgroup \ $
–俄罗斯
16 Sep 24'6:54
\ $ \ begingroup \ $
@Ruslan是的,您可以将其发布为另一个答案。
\ $ \ endgroup \ $
–没了
16-09-24在8:56
#5 楼
除了别人说的以外,您的程序现在正在运行,因为iostream
恰好有一个#include <string>
,但这不是必需的。最好包含您正在使用的内容,这样您就知道该程序在任何情况下都可以使用,除了您的2个包含项之外,您还应该添加#include <string>
#6 楼
在开始时,应尽可能避免不良做法。请勿使用
namespace std
;这是不好的做法,以后会伤害您。因此,请尽快将其删除,并在需要时开始添加std::
。std::reverse
是通用例程,因此,我建议您探索实现该目标的不同方法。 for (auto it = input.rbegin(); it != input.rend(); ++it) {
std::cout << *it++;
}
std::cout << std::endl;
请注意,这段代码将使您的字符串不受影响,而您当前的代码实际上是反转字符串,然后将其打印出来。
评论
\ $ \ begingroup \ $
(我最喜欢的折衷方法是使用std :: cout;。)
\ $ \ endgroup \ $
–灰胡子
16-09-23在8:28
\ $ \ begingroup \ $
如果一次引出整个字符串比一次引出一个字符的效率更高,我不会感到惊讶。
\ $ \ endgroup \ $
–coderodde
16-09-23在8:42
\ $ \ begingroup \ $
@coderodde可能是正确的,但是这样做的主要原因是数据保持不变
\ $ \ endgroup \ $
– miscco
16-09-23在9:03
\ $ \ begingroup \ $
我投票赞成,因为您使用的是auto&it。您很幸运,任何临时都可以转换为const ref,这就是为什么所引用的对象仍然有效。反正应该是自动的吧
\ $ \ endgroup \ $
–难以置信
16-09-23在11:35
\ $ \ begingroup \ $
@misco为什么不编辑答案来修复代码?
\ $ \ endgroup \ $
–俄罗斯
16-09-24在7:01
#7 楼
我可以在一个简短的程序中给出的唯一提示是,您可以消除running
布尔变量:while(true)
{
string input;
cout << "[Enter 'exit' to exit the program]\n";
cout << "Enter the text you want to reverse: ";
getline(cin, input);
if (input.compare("exit") == 0)
{
break;
}
reverse(input.begin(), input.end());
cout << "The reversed version of your text is: " << input << endl << endl;
}
希望有所帮助。
#8 楼
假设您实际上希望用户输入脱离程序而不是使用Ctrl-C,则可以执行以下操作:说了关于您的基础知识,但在本示例中已经实现了它们。
#9 楼
在这种情况下,这实际上不是必需的,但是如果您要写一个大字符串的反义字,那么就不应该就位反转它然后打印。而是直接打印它:std::copy(in.rbegin(), in.rend(),
std::ostreambuf_iterator<char>(std::cout));
在循环中使用
std::ostreambuf_iterator
比在循环中使用operator<<
更可取,因为后者会为每个单个字符构造一个哨兵对象而产生开销,而前者只需要一个哨兵。评论
\ $ \ begingroup \ $
看一下miscco的答案。
\ $ \ endgroup \ $
–灰胡子
16-09-24在7:03
\ $ \ begingroup \ $
@greybeard我以前没看过,谢谢指出。我仍然认为我的答案是合理的:它显示了执行此处最简单的操作的唯一(?)方法:反向打印字符串(在单个输出操作中)请参见我的编辑。
\ $ \ endgroup \ $
–Daniel Jour
16 Sep 24 '17:10
评论
几乎从来没有将布尔值与(运行)或while(!找到)进行比较。它不处理unicode(或任何多字节编码)
@JoopEggen为什么不呢?我希望您不是要说永远不要将两个布尔值相互比较
@Celeritas比较布尔值始终是一种难得的乐趣,可用于等效等。因此认为“差不多”。但是,如果(正在运行==假)==假,则有人会听到思考。
for循环也应该是if(!getline(cin,input)|| input ==“ exit”)。