• 对C++ Primer的10.3.9单词转换的思考



    这篇代码有几个知识点可以复习一下,而且小白学到了新知识o(╯□╰)o
     1 #include <iostream>
     2 #include <string>
     3 #include <map>
     4 #include <fstream>
     5 #include <sstream>
     6 using namespace std;
     7 
     8 ifstream& open_file(ifstream&,const string&);
     9 /*two input main parameter of main:
    10 *The first is name of the word transformation file
    11 *The second is name of the input to transform
    12 */
    13 int main(int argc, char  **argv )    
    14 {
    15     /*Use to hold the pair of word and trans_word:
    16     Key is the word to look for in the input, Value is the word to use in the output
    17     */
    18     map<string, string> trans_map;
    19     string key, value;
    20     if(argc != 3)
    21         throw runtime_error("Wrong number of arguments!");
    22     ifstream map_file;
    23     if (!open_file(map_file, argv[1]))
    24     {
    25         throw runtime_error("No transformation file!");
    26     }
    27     //read the transformation map and build the map
    28     while (map_file >>key >>value)
    29         trans_map.insert(make_pair(key, value));
    30 
    31     ifstream input;
    32     if(!open_file(input, argv[2]))
    33         throw runtime_error("No input file!");
    34     string line;    //hold each line from the input
    35     
    36     //read the text to transform it a line at a time 
    37     while ( getline(input, line)) //read a line from the input to line
    38     {
    39         istringstream stream(line);
    40         string word;
    41         bool firstword = true;
    42         while (stream >>word)
    43         {
    44             /*Use word find the key of trans_map*/
    45             map<string, string>::const_iterator  map_it = trans_map.find(word);
    46             if (map_it !=trans_map.end())
    47                 /*if there is substitute for word, change the word*/
    48                 word = map_it->second;
    49                 if (firstword)
    50                     firstword = false;
    51                 else
    52                     cout << " ";
    53                 cout << word;
    54             }
    55             cout << endl;
    56         }
    57         return 0;
    58 }
    59 
    60 ifstream& open_file(ifstream &in, const string &file )
    61 {
    62     in.close();
    63     in.clear();
    64     in.open ( file.c_str() );//open the file we were given
    65     return in;
    66 }

    首先理清楚单词转换的流程:

    1.明确输入文件有两个:
      ①mapfile,单词转换集合,其第一个值为待转换单词,第二个值为转换后单词
      ②infile,输入文件
    2.明确对文件的操作
      ①对于mapfile,如果打开正确的话,读入单词转换对,将其转化为:第一个值为key,第二个值为value;调用insert在容器中插入新元素,循环执行。
      ②对于infile,使用getline函数逐行读取文件,将文件的每个单词在map_file中查找,若找到则用map_file中的value将其替代,最后输出。注:输出空格的细节! 

    知识点总结:

    1.main函数的形参

      main(int argc, char **argv); 

    argc是一个整型变量,指的是命令行输入参数的个数,argv是字符串数组,它包含argc个字符串,每个字符串存储着一个命令行参数,其也可以写作char *argv[]。

    如该例子argv[0]存储的是命令名,argv[1],argv[2]存储着执行该程序所需要的两个文件名参数。

    argc和argv就是一个名字,可以改变的,如写成arc和arv,丝毫不影响。

    对形参个数的检查:

    if(argc != 3)
      throw runtime_error("Wrong number of arguments!"); 

     2.文件打开

    ifstream& open_file(ifstream &in, const string &file )
    {
        in.close();
        in.clear();
        in.open ( file.c_str() );//open the file we were given
        return in;
    }

    输入的两个参数:文件流和文件名

    最后要么将in和指定文件绑在了一起,要么处于错误条件状态。

    错误使用throw runtime_error

    3.文件读取

    对于文件1,将输入的文件中的单词转换对使用make_pair创建pair对象trans_map。

    再用insert函数,如果key不存在,则添加。

    while (map_file >>key >>value)
        trans_map.insert(make_pair(key, value));

    对于文件2,首先使用getline逐行读入,istringstream对象可以绑定一行字符串,然后以空格为分隔符把该行分隔开来。

    (例:

    stringstream strm(s); //创建存储s的副本的 stringstream 对象,其中 s 是 string 类型的对象

        while ( getline(input, line)) //read a line from the input to line
      { istringstream stream(line);
    string word; bool firstword = true; while (stream >>word) { /*Use word find the key of trans_map*/ map<string, string>::const_iterator map_it = trans_map.find(word); if (map_it !=trans_map.end()) /*if there is substitute for word, change the word*/ word = map_it->second; if (firstword) firstword = false; else cout << " "; cout << word; } cout << endl; }

    从输入文件中一个个读入单词word,如果能在trans_map的key中找到,则将word更改为trans_map的value值,循环录入,使用迭代器:

    map<string, string>::const_iterator  map_it = trans_map.find(word);

    最后输出word。

    答案中还考虑了空格的录入,但是为什么不直接输出cout << word<<" "; ??

    if (firstword)
        firstword = false;
    else
        cout << " ";

    4.技术小白的一点收获

    知道了怎么向main函数传递参数:

    通过 项目---属性---配置属性---调试---命令参数惊醒main函数参数的添加,各个参数之间以空格隔开;注意此时添加进去的参数被依次保存为argv[1]、argv[2]……

    argc也相应进行的增加,其中第一个参数argv[0]是编译器自动传入的生成的.exe所在的路径。之后在main函数中可以通过printf把已经传入的参数个数和相应的参数内容打印出来,此时的参数类型都是字符串类型的,如果需要要进行相应的类型转化。

    当然还有Dos的方法,

    “运行”->cmd->d:ef.exe g1 g2 g3...... 

    不过为嘛不可以???待解?

  • 相关阅读:
    python学习-33 max和min函数的高级使用
    XML--XSL
    XML--XML概览
    Linux|Zookeeper--CentOS7开机启动Zookeeper
    VMWare WorkStation15--Win10下开机启动虚拟机
    Zookeeper--命令介绍
    Zookeeper--复制模式安装
    Zookeeper--Zookeeper单机安装
    soupui--替换整个case的url
    Git--cherry-pick
  • 原文地址:https://www.cnblogs.com/betteryi/p/3775381.html
Copyright © 2020-2023  润新知