这是我的尝试:
#include <iostream>
#include<string>
using namespace std;
int main()
{
string s("hello world!..!.");
for (auto &c : s)
if(!ispunct(c))
{
cout<<s;
}
}
这是输出
亲爱的世界!..!你好世界!..!你好世界!..!你好世界!..!你好世界!...! 你好世界!..!你好世界!..!你好世界!..!你好世界!..!你好世界!...! 你好世界!..!。这是另一次尝试:
#include <iostream>
#include<string>
using namespace std;
int main()
{
string s("hello world!..!.");
for (auto &c : s)
if(!ispunct(c))
{
cout<<c;
}
}
这给出了正确的输出(即:hello world)
为什么cout<<s;
不会给我正确的输出?毕竟c
是引用,因此对c
的任何更改也适用于s
。或者我错了吗?
答案 0 :(得分:0)
s
是整个字符串,因此cout<<s
将整个字符串发送到输出流:\
您的第二次尝试有效,因为您正在向流中发送单个字符。但是,在第一次尝试中,您将为字符串中存在的每个字符发送整个字符串。计算字符串中非punct字符的数量,然后计算打印字符串的次数;)
答案 1 :(得分:0)
这就是为什么我不喜欢 auto 功能,在你的情况下auto是一个char并且没有从字符串中删除。
LE: ispunct 不会从字符串中删除字符,它甚至不知道(或关心)您有字符串,它只返回true如果字符是标点字符,则为false;如果不是,则根据该返回执行cout语句,其中字符不是标点符号或不是标点符号。
答案 2 :(得分:0)
ispunct
不会消除punct
的字符。 仅返回0
或non-zero
来表示
如果是punct
或no
。
当您遇到不是punct
的字符时,它会返回0
。然后输入if
。您正在打印整个字符串s
。
然而,对于cout<<c
,您只打印字符(非punct
,因为您现在处于循环中)
答案 3 :(得分:0)
另一种变体,使用STL算法:
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
using std::cout;
using std::endl;
using std::string;
using std::back_inserter;
using std::copy_if;
int main()
{
string s("hello world!..!.");
string result = "";
copy_if(begin(s), end(s),
back_inserter(result),
[](char c){return !ispunct(c);}
);
cout << result << endl;
}
对于真实世界的代码,建议在循环中使用合适的STL算法,因为说copy_if
清楚地表明了你的意图,并没有关注各个步骤。在这个例子中它是否更好我不想判断。但是记住这种可能性肯定是好的!
还有一件事:编写using namespace std
通常被认为是一件坏事,因为当未来版本的C ++引入了您已经在自己的代码中定义的新关键字时,这会导致名称冲突。要么一直使用前缀std::
,要么按照我在示例中显示的方式,这样可以保证您的代码安全。