| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 773 人关注过本帖
标题:如何在c程序里,读取两个文档疑问
只看楼主 加入收藏
cpp_初学者
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2011-6-30
收藏
得分:0 
回复 10楼 succubus
非常感谢您的无私分享 :)
我之前对awk,sed,perl及基本的unix command,比较熟悉。
我多数都是用综合以上的语言,来处理文档。
但最近发觉,在处理某些较大的文档(>1Gb),我会遇到该程序需要花费很长的时间处理文档及没有足够记忆(RAM)分析文档。
因此,才希望了解c语言,是如何分析相同的文档。
我会再详读您的每行code,希望能理解您所用的逻辑。
谢谢
2011-07-12 17:00
cpp_初学者
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2011-6-30
收藏
得分:0 
回复 10楼 succubus
你好,我尝试篇写您的c程序,让其能自由读取任何输入的文档。
理想操作格式:
./cpp_program_name [input_file1_name] [input_file2_name] [output_file_name]

以下是我利用您的c程序,篇改的内容:
程序代码:
#include <stdio.h>
#include <string>
#include <map>
#include <fstream>
#include <vector>

using namespace std;

int main(int argc, char *argv[])
{
       map<string, string> outMap;
       vector<string> keys;

       char buf[4096];
       FILE *fin1, *fin2, *fout;

       if(argc != 4)
       {
               fprintf(stderr, "Usage:  ./cpp_program_name [input_file1_name] [input_file2_name] [output_file_name]\n", argv[0]);
               return(1);
       }

       fin1=fopen(argv[1], "r");
       if(fin1 == NULL)
       {
              fprintf(stderr, "Couldn't open %s\n", argv[1]);
              return(1);
       }
       fin2=fopen(argv[2], "r");
       if(fin2 == NULL)
       {
              fprintf(stderr, "Couldn't open %s\n", argv[2]);
              return(1);
       }


       fout=fopen(argv[3], "w");
       if(fout == NULL)
       {
              fprintf(stderr, "Couldn't open %s\n", argv[3]);
              return(1);
       }
    string key;
    string word;
    string line;
    int delimiterPos;
    map<string, string>::iterator searchRes;
    while(fgets(buf, 4096, fin1))
{
    while (fin1 >> key)
    {
        keys.push_back(key);
        outMap.insert(make_pair(key, "|"));
    }
}
    while(fgets(buf, 4096, fin2))
{
    while (fin2 >> line)
    {
        delimiterPos = line.find('|');
        key = line.substr(0, delimiterPos);
        word = line.substr(delimiterPos);
        if ((searchRes = outMap.find(key)) != outMap.end())
            searchRes->second = word;
    }
}
    for (vector<string>::iterator iter = keys.begin(); iter != keys.end(); ++iter)
    {
        searchRes = outMap.find(*iter);
        fout << searchRes->first << searchRes->second << endl;
    }
    fclose(fin1);
    fclose(fin2);
    fclose(fout);

    return 0;
}

当我试着解码以上程序时:
程序代码:
[home@cpp]g++ cpp_program.cpp
cpp_program.cpp: In function aint main(int, char**)a:
cpp_program.cpp:50: error: no match for aoperator>>a in afin1 >> keya
cpp_program.cpp:58: error: no match for aoperator>>a in afin2 >> linea
cpp_program.cpp:70: error: no match for aoperator<<a in afout << searchRes.std::_Rb_tree_iterator<_Tp>::operator-> [with _Tp = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]()->std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::firsta

您是否知道,该如何篇改,才能让您的c程序,依照理想操作形式的格式,运行及分析文档?
理想操作格式:
./cpp_program_name [input_file1_name] [input_file2_name] [output_file_name]
2011-07-12 17:31
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
没想到这样就可以了……
但用 stl 库,数据结构全是放在内存里的。楼主说内存不够使,这样的程序我本来以为会跑不下来。

succubus 的实现和我想的很相似,基本就是先把文档1的内容排一下序(map 是用红黑树实现的,所以二分查找的效果就会比较好),然后走文档2的时候好找关键字。

另外,楼主的错误提示里怎么感觉每行都有那么多 a 呀?是那个提示本来就是这样的吗?那把那个提示说的错误行,在代码里注一下。
2011-07-12 19:54
succubus
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:635
专家分:1080
注 册:2007-10-7
收藏
得分:0 
你改写后的程序fin1,fin2,fout已经是C库里的FILE*了
既然是C里的东西自然不可能重载运算符<<和>>。

另外你对awk,PERL等比较熟悉,其实也可以使用boost库,里面有正则表达式可以用

[url=http:///view/aDU1]/image/aDU1.gif" border="0" />[/url]
2011-07-12 20:15
cpp_初学者
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2011-6-30
收藏
得分:0 
回复 13楼 pangding
你好,以下三行,是错误的代码,我现在还在努力修正中
程序代码:
#include <stdio.h>
#include <string>
#include <map>
#include <fstream>
#include <vector>

using namespace std;

int main(int argc, char *argv[])
{
       map<string, string> outMap;
       vector<string> keys;

       char buf[4096];
       FILE *fin1, *fin2, *fout;

       if(argc != 4)
       {
               fprintf(stderr, "Usage:  ./cpp_program_name [input_file1_name] [input_file2_name] [output_file_name]\n", argv[0]);
               return(1);
       }

       fin1=fopen(argv[1], "r");
       if(fin1 == NULL)
       {
              fprintf(stderr, "Couldn't open %s\n", argv[1]);
              return(1);
       }
       fin2=fopen(argv[2], "r");
       if(fin2 == NULL)
       {
              fprintf(stderr, "Couldn't open %s\n", argv[2]);
              return(1);
       }


       fout=fopen(argv[3], "w");
       if(fout == NULL)
       {
              fprintf(stderr, "Couldn't open %s\n", argv[3]);
              return(1);
       }
    string key;
    string word;
    string line;
    int delimiterPos;
    map<string, string>::iterator searchRes;
    while(fgets(buf, 4096, fin1))
{
    while (fin1 >> key)
    {
        keys.push_back(key);
        outMap.insert(make_pair(key, "|"));
    }
}
    while(fgets(buf, 4096, fin2))
{
    while (fin2 >> line)
    {
        delimiterPos = line.find('|');
        key = line.substr(0, delimiterPos);
        word = line.substr(delimiterPos);
        if ((searchRes = outMap.find(key)) != outMap.end())
            searchRes->second = word;
    }
}
    for (vector<string>::iterator iter = keys.begin(); iter != keys.end(); ++iter)
    {
        searchRes = outMap.find(*iter);
        fout << searchRes->first << searchRes->second << endl;
    }
    fclose(fin1);
    fclose(fin2);
    fclose(fout);

    return 0;
}
2011-07-13 19:27
cpp_初学者
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2011-6-30
收藏
得分:0 
回复 14楼 succubus
谢谢你的细心帮忙和解释,我还在努力改正中
2011-07-13 19:28
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
收藏
得分:7 
我是这样想的,也是制作一个mulitimap容器,first值为文档一里面的每个值,second为一个指向文档二的文件指针,然后对着文档二里的每个值,查找在map容器中有无匹配的,有的话返回文件指针位置并使second值指向文档二的那个值,容器完成后,就可以输出了,不知道性能方面如何?
2011-07-13 20:27
specilize
Rank: 4
等 级:业余侠客
帖 子:126
专家分:247
注 册:2011-2-20
收藏
得分:0 
说错了,second变量应该是文件读取位置的std::ios::pos_type变量
2011-07-13 20:33
快速回复:如何在c程序里,读取两个文档疑问
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019634 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved