编写一个程序,读取包括标点符号在内的字符串,并写入已读取但删除了标点符号的内容

时间:2013-06-11 13:08:55

标签: c++ string c++11 reference

这是我的尝试:

#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。或者我错了吗?

4 个答案:

答案 0 :(得分:0)

s是整个字符串,因此cout<<s将整个字符串发送到输出流:\

您的第二次尝试有效,因为您正在向流中发送单个字符。但是,在第一次尝试中,您将为字符串中存在的每个字符发送整个字符串。计算字符串中非punct字符的数量,然后计算打印字符串的次数;)

答案 1 :(得分:0)

这就是为什么我不喜欢 auto 功能,在你的情况下auto是一个char并且没有从字符串中删除。

LE: ispunct 不会从字符串中删除字符,它甚至不知道(或关心)您有字符串,它只返回true如果字符是标点字符,则为false;如果不是,则根据该返回执行cout语句,其中字符不是标点符号或不是标点符号。

答案 2 :(得分:0)

ispunct不会消除punct的字符。 仅返回0non-zero来表示 如果是punctno

当您遇到不是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::,要么按照我在示例中显示的方式,这样可以保证您的代码安全。