备战ccf


备战ccf之文本处理

说是备战ccf,其实就是我想总结一下用到的文件输入输出和文件读写,以及关于一些文本处理的东西而已

输入输出

scanf("%d %c %s %f %lf",&int,&char,&char*,&float,&double);//效率高,在较大数据输入的题中用于优化输入速度,但一般不如cin写起来爽
printf("%5d%%%4.2f",123,3.1415);
//result:  123%3.14
//输出效率高,不过其实一般不用输出这么多东西,但有时候比cout方便些,因为好格式化输出
cin>>a>>b;
cout<<setw(6)<<setprecision(2)<<3.1415<<endl;
//result:  3.14

下面来重点讲讲getline:

先讲下应用场景:当 cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读,当它读取到下一个空白字符时,它将停止读取,而getline则是读到换行符才会停止读取

下面是它的函数原型和日常使用:

istream&getline(istream&is,string a,char b);//is为输入流,而a是将输入流的内容保存到的地方,b为读取终止符,默认为'\n'
getline(cin,str);//常用写法,将遇到换行前的内容保存到str中

注意点:

  1. 如果将cin和getline混用时,在getline前使用的cin需要先清理cin中的缓存再使用,简单点就是可以用个getcahar()来把回车读了。
  2. 以下代码会陷入死循环
string str;
while(getline(cin,str)){}//这样只有当你到达EOF才能终止循环,但是如果把cin换为文件输入流,这又行了

文件读写

接下来讲讲文件读写,这玩意我是写一次程序百度一次,因为不怎么用,都是直接用给的样例(逃
但在开发十分重要,你说你读个文件都不会,还敲个屁代码(我骂我自己了属于是)
哦这个ccf应该用不到

本文只写一些我自己常用的操作,并不会特别系统的记录读写的所有操作

此处略过c的读写操作
c++基本都是使用fstream之类的流来进行操作
ifstream为文件读入流,ofstream为文件写入流,还要认识以下<<和>>这两个运算符,其中插入器(<<)向流输出数据,如向默认输出流cout也就是显示器输出,而析取器(>>)为从流输出数据,如默认输入流cin即是键盘。
下面给出示例代码:

ifstream infile("123.txt");//从123.txt中拿数据
string str;
infile>>str;//将123.txt的内容以string类型存在str中,遇到空格停
if(infile.eof()) ShowMessage("已经到达文件尾!");//成员函数eof()用来检测是否到达文件尾,如果到达文件尾返回非0值,否则返回0。
char ch;
string text;
while(infile.get(ch)){text+=ch;}//一个一个字符的读,并加入到text中,此代码代表将123.txt中所有数据读到text中
ofstream offile;
offile.open("234.txt");//向234.txt中写入数据
offile<<"456";//写入456
offile.put('c');//向流写一个字符'c'
//读写二进制数据文件
int n[5];
infile.read((unsigned char*)n,sizeof(n));//从123.txt读5个数到n中,注意类型转换
offile.write(text.c_str(),text.length());//乱写的
infile.close();//记得关哦
offile.close();

文本处理

这里主要涉及到对一堆字符串的处理,该部分包括stringstream的使用,字符串一堆函数的奇妙融合,正则表达式的使用

stringstream

先讲讲sscanf和sprintf,看这篇文章吧,sscanf/sprintd

stringstream主要的应用是将字符串转换相应的格式化数,还有按空格自动帮你分开字符串。

无内鬼,来点代码:

stringstream ss;
string s="123 456.12";
ss<<s;
int a;
double b;
ss>>a>>b;//a=123,b=456.12
template<class T>
string myto_string(const T& t)//将T转成string
{
        ostringstream oss;//创建一个流
        oss<<t;//把值传递如流中
        return oss.str();//获取转换后的字符转并将其写入result
}
string str1("123456");
ss.str(str1);
ss.seekp(0,ios::end);//流指针的移动
ss<<"hello";
cout<<ss.str()<<endl;//123456hello
ss.clear();//清空
ss<<setw(3)<<setfill('0')<<7;//输出007

补充:C++:string和stringstream用法总结

这里我将给出ccf一些文本处理的题

一、模板生成系统

附上我的代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int m, n;
    cin >> m >> n;
    vector<string>text;
    string line;
    getchar();
    for (int i = 0; i < m;i++){
        getline(cin, line);
        text.push_back(line);
    }
    unordered_map<string, string> um;
    string key, value;
    for(int i=0; i<n;i++){
        getline(cin, line);
        auto pos = line.find(" ");
        key = line.substr(0, pos);
        value = line.substr(pos+2,line.length()-pos-3);
        um[key] = value;
    }
    for(auto&e: text){
        auto pos1 = e.find("{{ ");
        auto pos2 = e.find(" }}",pos1);
        while(pos1 !=string::npos&&pos2!=string::npos){
            string str1=e.substr(pos1+3, pos2-pos1-3);
            if(um.count(str1)){
                e = e.replace(pos1, pos2 - pos1 + 3,um[str1]);
                pos2 = um[str1].length() + pos1;
            }
            else{
                e = e.replace(pos1, pos2 - pos1 + 3,"");
                pos2 = pos1;
            }
            pos1 = e.find("{{ ",pos2);
            pos2 = e.find(" }}",pos1);
        }
    }
    for(auto e:text){
        cout << e << endl;
    }
    return 0;
}

二、路径解析

正则表达式

这东西常用于模糊搜索,例如在一段字符串寻找逗号或者句号。我这里只涉及c++regex库的常用操作

首先,关于正则表达式的写法,请看这里

先给出正则表达式初始化,regex pattern1("(.*?)[,.]");//非贪婪匹配逗号或句号前任意字符串

然后讲讲匹配结果match_results这一模板类,其根据匹配到的结果的实例化类型包括下面这些:

typedef match_results<const char*> cmatch;
typedef match_results<const wchar_t*> wcmatch;
typedef match_results<string::const_iterator> smatch;
typedef match_results<wstring::const_iterator> wsmatch;//宽字符串迭代器

常用正则操作:

  1. regex_match :用于将目标串和正则表达式匹配,返回一个 bool 值,true 为匹配,false 为不匹配。整个字符串必须完全和正则表达式相匹配,不能有多余的字符,如果需要部分匹配则应使用 regex_search

  2. regex_search :只需要有个子串匹配即返回true

  3. regex_replace : 替换

样例:

regex pattern1("(.*?)[,.]");//非贪婪匹配逗号或句号前任意字符串
string::const_iterator iterStart = text.begin(); //迭代器声明
string::const_iterator iterEnd = text.end();
string temp;
smatch results;
while (regex_search(iterStart,iterEnd,results,pattern1))
{
    temp = results[0];
    sentences_.push_back(temp);
    iterStart = results[0].second; //更新搜索起始位置,搜索剩下的字符串
}
regex pattern2("[,.]");//匹配逗号或句号
auto result = regex_replace(sentences_[i], pattern2, "");//剔除逗号和句号,返回替换后的字符串

就写到这吧,累了。。。。


文章作者: Wdstql
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Wdstql !
评论
  目录