2

这是我的尝试:

#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

4 回答 4

0

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

您的第二次尝试有效,因为您将单个字符发送到流中。不过,在第一次尝试中,您要为字符串中存在的每个字符发送整个字符串。计算字符串中非标点字符的数量,然后计算字符串被打印出来的次数;)

于 2013-06-11T13:14:24.683 回答
0

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

LE:ispunct不会从字符串中删除字符,它甚至不知道(或关心)你有一个字符串,它只在字符是标点字符时返回 true,否则返回 false,并基于该返回cout 语句以非标点字符执行或不为标点字符执行。

于 2013-06-11T13:18:44.953 回答
0

ispunct不消除字符是 a punct它只返回0ornon-zero来表明它是punctor no

当您遇到一个不存在的字符时punct,它会返回0。你输入你的if. 您正在打印s整个字符串。

然而,cout<<c你只打印字符(这是 non punct,因为你现在处于循环中)

于 2013-06-11T13:24:39.197 回答
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::,要么按照我在示例中显示的方式进行操作,这样可以保证您的代码安全。

于 2013-06-11T15:25:13.557 回答