C++ Primer 4th 文本查询程序 bug,已修正,望指点另一种方法。

LENOVO_ 2010-05-15 07:20:54
C++ Primer 4th 文本查询程序 bug

直接进入主题:

使用 TextQuery 类查询单词出现的次数和行号。

hello,world!
for(;;);
std::string
line>>word


对于上面的文本内容,查询 hello、for、std、string、line、word 都是查不到的。
原因在于:

istringstream line(lines_of_text[line_num]);
string word;
while(line >> word)
word_map[word].insert(line_num);

line>>word 是以空格符为分隔符,所以提取不出来上面说的那些单词。

我的改进:(思路就是把',','.',';',':','(',')','&','<','>','_','+'替换成空格符)


void TextQuery::build_map()
{
for(line_no line_num=0;
line_num != lines_of_text.size();
++line_num)
{


string line_string=lines_of_text[line_num];
char separators[11]={',','.',';',':','(',')','&','<','>','_','+'}; //11
char blank(' ');
vector<char> v_str;
for(size_t i=0;i != line_string.size();++i)
v_str.push_back(line_string[i]);
for(size_t i=0;i<11;++i)
replace(v_str.begin(),v_str.end(),separators[i],blank);
string new_line_string(v_str.begin(),v_str.end());
istringstream line(new_line_string);


string word;
while(line >> word)
word_map[word].insert(line_num);
}
}


为了使用 STL 的replace泛型算法,我不得不把 string 装进 vector,处理之后又得把 vector 还原成 string .
现在这样就好了,修正bug.

我的问题,istringstream默认以空格符和 '\n' 为分隔符,能不能自己设置分隔符,如 ',' '.' ?
有什么成员函数可以做这个事情?
...全文
159 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
heshi1314 2010-11-01
  • 打赏
  • 举报
回复
学习了。流也可以自己做啊
LENOVO_ 2010-05-16
  • 打赏
  • 举报
回复
EN恩,加菲猫,你辛苦了。你贴的那个代码我早些时候已经看过了,好朦胧不懂。

继续坐等,静候。。。

我的另一种思路就是在打印结果的时候查找子串,有子串就打印出来。和第一种思路不同,
但这种思路还是有bug.

如:

helloworld

查找hello 肯定可以找到,但helloworld 不是 hello.
wade_2003 2010-05-16
  • 打赏
  • 举报
回复
就用strtok()函数,简单易懂
wade_2003 2010-05-16
  • 打赏
  • 举报
回复
就用strtok()函数,简单易懂
cattycat 2010-05-16
  • 打赏
  • 举报
回复
strtok是可以的,不过这个是c的库函数
selooloo 2010-05-16
  • 打赏
  • 举报
回复
用strtok分割字符串


#include <string.h>
#include <stdio.h>

int main(void)
{
char input[] = "hello,world!\nfor(;;);\nstd::string\nline>>word";
char *p,*delm=",()!\n;:>";

p = strtok(input, delm);
while(p)
{
printf("%s\n", p);
p = strtok(NULL, delm);
}
getchar();
return 0;
}
stilling2006 2010-05-15
  • 打赏
  • 举报
回复
接个分,呵呵~
zmcomputer 2010-05-15
  • 打赏
  • 举报
回复
学习了……
cattycat 2010-05-15
  • 打赏
  • 举报
回复
好像可以设置自己的流。我刚百度了,费了好长时间才找到,自己也试过了,是可以的。
#include<iostream>
#include<locale>
#include<algorithm>
#include<sstream>
using namespace std;

struct commactype:ctype<char>
{
commactype():ctype<char>(get_table()){}
static ctype_base::mask const*get_table()
{
static ctype_base::mask*rc=0;
if(rc==0)
{
rc=new ctype_base::mask[std::ctype<char>::table_size];
fill_n(rc,ctype<char>::table_size,ctype_base::mask());
rc[',']=ctype_base::space;//设置自己的分隔符
rc['.']=ctype_base::space;
}
return rc;
}
};



int main()
{
istringstream iss("word,hello,we.can.do");
iss.imbue(locale(locale(),new commactype));
string word;
while(iss>>word){
cout<<word<<endl;
}
return 0;
}


这个链接也可以,但是有bug。总之都是继承ctype<char>,实现locale。
http://www.cppblog.com/bird/archive/2008/01/25/37603.html
LENOVO_ 2010-05-15
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cattycat 的回复:]
istringstream好像不能设置自己的分隔符。
没见过自己设置分隔符的。
[/Quote]
那只能用 replace 了?

求解。
cattycat 2010-05-15
  • 打赏
  • 举报
回复
istringstream好像不能设置自己的分隔符。
没见过自己设置分隔符的。

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧