免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: jerryzheng
打印 上一主题 下一主题

想删除一个string中的所有大于两格的空格字串 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2004-05-17 14:34 |只看该作者

想删除一个string中的所有大于两格的空格字串

呵呵,咱还是截取有用字符算了,ASCII码下特殊字符太多了,转换为string有太多的不可见字符

论坛徽章:
0
12 [报告]
发表于 2004-05-17 15:06 |只看该作者

想删除一个string中的所有大于两格的空格字串

算了,看你被扁的可怜的样子,呵呵.
if ( (ch == ' ') 前加句话
  1. if (
  2.             !(ch == '\t' || ch == '\r' || ch == '\n')
  3.             ||
  4.             ( ch < 0x20 )                        
  5.   )
  6.         continue;
复制代码

STL 用来玩这种小东东,不合适吧,酷的未必是最好的,除非你BOSS要你用STL表现下?
和STRING 类的转化可以用 CHAR *过渡下.

论坛徽章:
0
13 [报告]
发表于 2004-05-17 15:17 |只看该作者

想删除一个string中的所有大于两格的空格字串

1. 如果想删除一个string中的所有大于两格的空格字串,并且如果是一个空格的话不删除(这是你说的原话),这种情况没有什么简单的处理方法,自己编程实现。

2. 如果是想把多个空格合并成一个空格的话(我想这可能才是你的本意吧),除了windflowers1976所示那样的处理方法外,还可以象下面的程序那样借助stringstream来实现:

  1. #include <iostream>;
  2. #include <string>;
  3. #include <sstream>;
  4. using namespace std;

  5. int main()
  6. {
  7.   string s = "this  is a      test\t\t   string\n\n\n";
  8.   cout << "original string: " << s << "\n";

  9.   stringstream ss;
  10.   ss << s; // put s into ss
  11.   s = ""; // clear s
  12.   string t;
  13.   while( ss >;>; t ) { // extract strings from ss
  14.     s += t + ' ';
  15.   }
  16.   s.erase( s.end()-1 ); // erase the last character ' '

  17.   cout << "result string: " << s << endl;
  18. }
复制代码

这里将多个“空白字符”合并为一个空格符。一个字符是否是空白字符(whitespace)由 isspace() 函数判断。比如,空格、回车、制表等符号都是空白字符。

还有一种循环替换的方法,每次循环替换两个连续的空格"  ",直到没有双空格替换为止。就是效率稍微低了写。

>;>; 如果你的文件中有不可见字符,
>;>; 那么,
>;>; 从严格意义上来讲,你的文件就不是“文本文件”。
不正确。文本文件中可以包含空格、换行(或者回车)、制表等符号,尽管它们都是不可见的。

论坛徽章:
0
14 [报告]
发表于 2004-05-17 15:21 |只看该作者

想删除一个string中的所有大于两格的空格字串

stl 好像还不如windflowers1976的版本清晰。
如果非要使用stl,可以考虑以下实现:


  1. struct dblspace_check
  2. {
  3.         dblspace_check() : _last_space(false)
  4.         {
  5.         }

  6.         bool operator()( char value )
  7.         {
  8.                 bool lastspace = _last_space;
  9.                 _last_space = is_space(value);
  10.                 return (lastspace && _last_space);
  11.         }

  12. private:
  13.         //自己在这里写你的“不可见字符“判断吧
  14.         inline bool is_space(char value)
  15.         {
  16.                 return value == ' ' || value == '\t';
  17.         }

  18.         bool _last_space;
  19. };


  20.         //使用方法
  21.         string::iterator it = remove_if(str.begin(), str.end(), dblspace_check());
  22.         str.erase(it, str.end());

复制代码

       
[/code]

论坛徽章:
0
15 [报告]
发表于 2004-05-17 15:33 |只看该作者

想删除一个string中的所有大于两格的空格字串

[quote]原帖由 "linux_newbie"][/quote 发表:

看错了,看错了。不好意思。

论坛徽章:
0
16 [报告]
发表于 2004-05-17 18:18 |只看该作者

想删除一个string中的所有大于两格的空格字串

原帖由 "whyglinux" 发表:

看错了,看错了。不好意思。


我的确实有错误,但不是你说的那个。呵呵。
检查了一下,我这个算法有个隐藏的错误。在gcc/linux 和vc/windows下都有BUG。

例如,分析一个前面有3个空格的字符串,转换以后,结果前面还有两个空格,正确结果应该是前面只有一个空格了。

原因是由于remove_if里面调用了find_if,将我的函数对象pass-by-value, 结果以前保存的状态信息(_last_char)就丢失了。

麻烦!还不知道咋改!

论坛徽章:
0
17 [报告]
发表于 2004-05-17 19:00 |只看该作者

想删除一个string中的所有大于两格的空格字串

其实原因并不是你分析的那样丢失了状态信息,否则后面的操作也就不会成功了。主要的原因是因为初始化的问题,将_last_space初始化为false,也就是默认情况下字符串的第一个字符不是空白字符(因此,如果字符串的第一个字符是空白字符的话,程序会给出错误的结果)。

明白了原因,修改也就很容易了:通过类的构造函数传给_last_space一个初始状态,这个值根据字符串的第一个字符设定:

  1. struct dblspace_check
  2. {
  3. // dblspace_check() : _last_space(false) {}
  4.    dblspace_check(char c) {
  5.      _last_space = is_space( c );
  6.    }
  7. // ...
  8. };
复制代码

然后这样使用即可:

  1.   string::iterator it = remove_if(str.begin(), str.end(), dblspace_check( str[0] ));
  2.   str.erase(it, str.end());
复制代码

能写出这样的程序,说明对C++标准库的使用已经很有心得了。以后多到论坛上来看看,有问题一起探讨。

论坛徽章:
0
18 [报告]
发表于 2004-05-17 20:58 |只看该作者

想删除一个string中的所有大于两格的空格字串

相互学习。

另外,虽然我不敢100%肯定你的平台是否有这样的问题,但是在我测试的linux和windows下,错误的原因就是我说的pass-by-value(这个是由stl的源程序控制的,检查find_if就可以知道原因),因为我这个function对象是Stateful的。没办法,stl的源程序就是这样写的。运行的结果虽然按照你的方法也是正确的,但是实际上内部已经有问题了。


下面有篇文章:

http://www.awprofessional.com/ar ... =25142&seqNum=4

提到了这个问题,不过它的解决方法是采用一个独立的带引用计数的State对象,好像不太好。

internet上也有一些相关的帖子。 你可以搜索“remove_if  function object   reference".
你跟踪一下stl的源代码就知道了,function object实际上被创建了多次。
下面的我修改后的代码,保证这个函数对象不被多次创建。

前面的dblspace_check几乎一样,没有变化,只是加了一个定义。

  1. class dblspace_check
  2. {
  3. public:
  4.         dblspace_check() : _last_space(false) {
  5.         }

  6.         bool operator()( char value ) {
  7.                 bool lastspace = _last_space;
  8.                 _last_space = is_space(value);
  9.                 return (lastspace && _last_space);
  10.         }

  11. private:
  12.         //防御性设计,无实现。我主要用来防止编译器进行隐藏的转换。
  13.         dblspace_check(const dblspace_check& src);

  14.         inline bool is_space(char value)        {
  15.                 return value == ' ' || value == '\t';
  16.         }

  17.         bool _last_space;
  18. };

  19. //关键的TRefFunction对象,保证使用函数对象的引用。

  20. template <class T>;
  21. class TRefFunction
  22. {
  23. public:
  24.         inline TRefFunction(T& aRef) : iRef(aRef){
  25.         }


  26.         template<class V>; inline bool operator()(V v) {
  27.                 return iRef(v);
  28.         }
  29. private:
  30.         T& iRef;
  31. };


  32. 用法:

  33. dblspace_check fun;
  34. string::iterator it = remove_if(str.begin(), str.end(), TRefFunction<dblspace_check>;(fun));
  35. str.erase(it, str.end());
复制代码



gcc3.2.2 +linux 和 vc6 +windows都可以编译通过且运行正确。

论坛徽章:
0
19 [报告]
发表于 2004-05-18 05:30 |只看该作者

想删除一个string中的所有大于两格的空格字串

如果是想把多个空格合并成一个空格的话

  1. bool double_space_check(const char a, const char b)
  2. {
  3.    return  is_space(a) && is_space(b);
  4. }

  5. ......

  6. std::string result;
  7. unique_copy(str.begin(),str.end(), back_inserter(result), double_space_check);
复制代码

论坛徽章:
0
20 [报告]
发表于 2004-05-18 09:04 |只看该作者

想删除一个string中的所有大于两格的空格字串

unique_copy(str.begin(),str.end(), back_inserter(result), double_space_check);


哈哈,使用unique确实更加好, 不过你的代码这行编译有错误,string并没有push_back函数。另外,这样又需要分配一个新的string。

按照你的思路,其实使用unique就可以了。

unique(str.begin(),str.end(), double_space_check);

C++用到地方了,写出的代码确实简洁。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP