当字符串的最后一个位置是标点符号时程序停止解析

Posted

技术标签:

【中文标题】当字符串的最后一个位置是标点符号时程序停止解析【英文标题】:Program stops parsing when last position of string is punctuation 【发布时间】:2013-04-09 04:28:47 【问题描述】:

所以我试图从文件中读取所有单词,并在这样做时去掉标点符号。这是剥离标点符号的逻辑:

编辑:程序实际上完全停止运行,只是想弄清楚

ifstream file("text.txt");

string              str;
string::iterator    cur;

for(file>>str; !file.eof(); file>>str)
    for(cur = str.begin(); cur != str.end(); cur++)
         if (!(isalnum(*cur)))
            cur = str.erase(cur);
         
    
cout << str << endl;
...

假设我有一个文本文件,内容如下:

This is a program. It has trouble with (non alphanumeric chars)

But it's my own and I love it...

当我 coutendl; 我的字符串紧跟着这个逻辑之后,我会得到

This
is
a
program
It
has
trouble
with
non
alphanumeric

这就是所有人。 我的迭代器逻辑有问题吗? 我该如何解决这个问题?

谢谢。

【问题讨论】:

我不小心点击了编辑最后一个人的评论,结果丢失了。我很抱歉。 他可能决定自己删除它,没关系 对于它的价值,我使用的是 gcc 4.6.3,不确定我是否可以访问正则表达式。 Eclipse 没有编译它。 换行符如何进入字符串?我在您的代码中没有看到它,由于cur 未定义,它也没有真正编译,您是否显示您的实际代码? 据我了解,以及我如何使用它,file&gt;&gt;string 将传递空格或换行符之间的所有内容,无论它们相距多远。它对我有用。 【参考方案1】:

我看到的迭代器的主要逻辑问题是,对于非字母数字字符,迭代器增加了两次:在erase 期间,它移动到下一个符号,然后来自for 循环的cur++ 增加了它,所以它跳过非字母数字后的每个符号。

所以大概是这样的:

string              next;
string::iterator    cur;

cur = next.begin()
while(cur != next.end())
    if (!(isalnum(*cur)))
        cur = next.erase(cur);
     else 
        cur++;
    

这只是删除非字母数字字符。如果你需要标记你的输入,你将不得不做更多的事情,即记住,你是否在一个单词中(至少读过一个字母数字字符)并采取相应的行动。

【讨论】:

【参考方案2】:

在构建转换后的列表时不复制 in 标点符号怎么样。好的。可能是矫枉过正。

#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <cctype>
using namespace std;

// takes the file being processed as only command line param
int main(int argc, char *argv[])

    if (argc != 2)
        return EXIT_FAILURE;

    ifstream inf(argv[1]);
    vector<string> res;
    std::transform(istream_iterator<string>(inf),
        istream_iterator<string>(),
        back_inserter(res),
        [](const string& s) 
            string tmp; copy_if(s.begin(), s.end(), back_inserter(tmp),
            [](char c)  return std::isalnum(c); );
            return tmp;
        );

    // optional dump to output
    copy(res.begin(), res.end(), ostream_iterator<string>(cout, "\n"));

    return EXIT_SUCCESS;

输入

All the world's a stage,
And all the men and women merely players:
They have their exits and their entrances;
And one man in his time plays many parts,
His acts being seven ages. At first, the infant,
Mewling and puking in the nurse's arms.

输出

All
the
worlds
a
stage
And
all
the
men
and
women
merely
players
They
have
their
exits
and
their
entrances
And
one
man
in
his
time
plays
many
parts
His
acts
being
seven
ages
At
first
the
infant
Mewling
and
puking
in
the
nurses
arms

【讨论】:

美丽。谢谢你的诗。 请继续关注我的下一个问题,因为我正在摸索我的 map 以保持字频计数正常工作! @nzondlo 上面的代码加上一点按摩也使这变得微不足道,仅供参考。请记住:++mymap[str];,其中mymapstd::map&lt;string, unsigned int&gt;。当你开始编写下一个任务时,它就会出现。 谢谢,我有类似的东西。它正在打印该死的东西是我遇到麻烦的地方。 @nzondlo 请参阅this sample for an update。我也冒昧地将所有单词都小写了。希望对您有所帮助。【参考方案3】:

您应该使用ispunct 来测试标点符号。如果您还想过滤掉控制字符,您应该使用iscntrl

过滤掉标点符号后,您可以拆分空格和换行符来获取单词。

【讨论】:

以上是关于当字符串的最后一个位置是标点符号时程序停止解析的主要内容,如果未能解决你的问题,请参考以下文章

PS里打字怎么让标点符号不在第一个?

删除快速字符串的最后一个标点符号

去除文本中标点符号的java程序

java:获取字符串中第一个汉字和第一个汉字汉字标点符号的位置?

如何修复此代码,使其随机播放字母并且对第一个字母和最后一个字母、标点符号没有影响

从找到空格和标点符号的数组中删除字符[重复]