很重要的收集 --- 关于c++的各种输入(包括istream_iterator结合逗号分隔)

最近又开始刷题了,在这个过程中,我不断地发现一个问题,就是不同的题目会有不同的输入要求,而如果用c++这么繁复的语言在刷题的时候,有时候光是一个输入就会把所有的时间都消耗得一干二净,因此我在这里设立一篇文章用来记录不同的输入方式,本篇文章采取迭代更新的方式,一旦看到新的或者更好的输入方式我就会对这篇文章进行更新,同时也希望大家能对我的错误进行指出~


  • 读取文件内容
用C++读取目录下的123.txt文件内容,文件内容为:
023,456,789,012,345,678
234,567,890,123,456,789
345,678,901,234,567,890

这种一般用在读取一个邻接表,网络之类的
#include <fstream>
#include <sstream>
#include <iostream>
using namespace std;
int main()
    ifstream inf;
    inf.open("123.txt", ifstream::in);
    const int cnt = 6;          
    string line;
    //int i = 0;
    int j = 0;
    size_t comma = 0;
    size_t comma2 = 0;
    while (!inf.eof())
        getline(inf,line);
        comma = line.find(',',0);
        cout<<line.substr(0,comma).c_str()<<' ';
        while (comma < line.size() && j != cnt-1)
            comma2 = line.find(',',comma + 1);
            cout<<line.substr(comma + 1,comma2-comma-1).c_str()<<' ';
            comma = comma2;
        cout<<endl;
        j = 0;
    inf.close();
    return 0;
} 


以上的方式中inf.eof()的判断方式会出现一些问题!!!问题原因可以参考 C++之EOF() ,主要关系到eof判断到最后一个字符的逻辑。

所以,有网友建议使用 istream_iterator。

#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
    ifstream in_file("input_file.txt");
    ofstream out_file("output_file.txt");
    if(!in_file || !out_file)
        cout<<"filesopen failed!\n";
        return -1;
    istream_iterator<string> is(in_file);  // 自动按照空格分隔
    istream_iterator<string> eof;
    vector<string> text;
    copy(is,eof,back_inserter(text));
    sort(text.begin(),text.end());
    ostream_iterator<string> os(out_file," ");
    copy(text.begin(),text.end(),os);
    return 0;
}

但是这个样子,没有逗号分隔,要逗号分隔会比较麻烦一点,我这里写了一种方法可以做到。

#include <iostream>
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
#include <locale>
struct csv_reader: std::ctype<char> {
    csv_reader(): std::ctype<char>(get_table()) {}
    static std::ctype_base::mask const* get_table() {
        static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());
        rc[','] = std::ctype_base::space;
        rc['\n'] = std::ctype_base::space;
        rc[' '] = std::ctype_base::space;
        return &rc[0];
int main()
    ifstream in_file("input_file.txt");
    in_file.imbue(locale(locale(), new csv_reader()));
    ofstream out_file("output_file.txt");
    if(!in_file || !out_file)
        cout<<"filesopen failed!\n";
        return -1;
    istream_iterator<string> is(in_file);
    istream_iterator<string> eof;
    vector<string> text;
    copy(is,eof,back_inserter(text));
    sort(text.begin(),text.end());
    ostream_iterator<string> os(out_file," ");
    copy(text.begin(),text.end(),os);
    return 0;
}

istream_iterator是个很有意思的输入工具,也可以用来读取到set里。

fruits.txt:
banana 
apple 
strawberry 
blueberry 
peach 
apple 
----------------------------------------------------------------------------------------
#include <algorithm> 
#include <fstream> 
#include <iostream> 
#include <iterator> 
#include <set> 
#include <string> 
using namespace std; 
int main() 
    ifstream file("fruits.txt"); 
    set<string> M; 
    copy(istream_iterator<string>(file), 
     istream_iterator<string>(), 
     inserter(M, M.end())); 
    for (auto const& val : M) 
     cout << val << ", "; 
}


  • 读取输入(不确定个数)
输入的每个整数之间用空格隔开,个数不确定。
输入:3 4 1 2
int a;
vector<int> array;
while(cin.get() != '\n'){
    cin >> a;
    array.push_back(a);
}

也可以另一种

int a;
vector<int> array;
while(cin>>a){
    array.push_back(a);
}

还可以用istream_iterator。

#include<iostream>
#include<string>
#include<iterator>
#include<algorithm>
using namespace std;
int main()
    string text;
    istream_iterator<int> is(cin);//绑定标准输入装置
    istream_iterator<int> eof;//定义输入结束位置
    copy(is,eof,back_inserter(text));
    sort(text.begin(),text.end());
    ostream_iterator<int> os(cout,", ");//绑定标准输出装置
    copy(text.begin(),text.end(),os);
}

逗号分隔!!!(输入的字符串是逗号分开的)

#include <vector>
#include <string>
#include <sstream>
#include <iostream>
int main()
    std::string str ="1,2,3,4,5,6";
    std::vector<int> vect;
    std::stringstream ss(str);
    int i;
    while (ss >> i)
        vect.push_back(i);
        if (ss.peek() == ',')
            ss.ignore();
    for (i=0; i< vect.size(); i++)
        std::cout << vect.at(i)<<std::endl;
~或者,更简洁的办法~
stringstream ss("1,1,1,1, or something else ,1,1,1,0" );
vector<string> result;
while( ss.good() )
    string substr;
    getline( ss, substr, ',' );
    result.push_back( substr );
}
  • 读取输入(确定个数)
#include<bits/stdc++.h>
using namespace std;
int main()
    vector<int> array;
    int n; int a;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a;
        array.push_back(a);
    //这里对数组进行操作
    return 0;
}
有时候题目会给你一个二维的数组,m*n
比如:
4 4
*000
00*0
00**
0*00
#include <iostream>
#include <vector> 
using namespace std;
//打印二维vector
void printVec(vector<vector<char> >  vec)
    vector<char> vec_tmp;
    for (vector<vector<char> >::iterator iter = vec.begin(); iter != vec.end(); iter++)
        vec_tmp = *iter;
        for (vector<char>::iterator it = vec_tmp.begin(); it != vec_tmp.end(); it++)
            cout << *it << " ";
        cout << endl;
int main(int argc,char* argv[])
    int m,n;
    cin>>m>>n;
    //给定行数、列数的二维vector初始化
    vector<vector<char> > a(m,vector<char>(n));
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            cin>>a[i][j];
    printVec(a);
    return 0;
}
  • 字符串输入
#include<bits/stdc++.h>
using namespace std;
int main(){
	string s;
	getline(cin, s);
	cout << s << endl;
}
接受一个字符串,遇“空格”、“Tab”、“回车”都结束
#include <iostream>
using namespace std;
main ()
char a[20];
cin>>a;
cout<<a<<endl;
输入:jkljkljkl
输出:jkljkljkl
输入:jkljkl jkljkl //遇空格结束,所以不能输入多个单词
cin.get(字符变量名)可以用来接收字符
#include <iostream>
using namespace std;
main ()
char ch;
ch=cin.get(); //或者cin.get(ch);只能获取一个字符
cout<<ch<<endl;
输入:jljkljkl
输出:j
cin.get(字符数组名,接收字符数)用来接收一行字符串,可以接收空格
#include <iostream>
using namespace std;
main ()
char a[20];
cin.get(a,20); //有些类似getline。可以输入多个单词,中间空格隔开。
cout<<a<<endl;
输入:jkl jkl jkl
输出:jkl jkl jkl
输入:abcdeabcdeabcdeabcdeabcde (输入25个字符)
输出:abcdeabcdeabcdeabcd (接收19个字符+1个'\0')
cin.get(无参数)没有参数主要是用于舍弃输入流中的不需要的字符,或者舍弃回车,弥补cin.get(字符数组名,接收字符数目)的不足.
#include <iostream>
using namespace std;
int main(void)
    char arr[10];
    cin.get(arr,10);
    cin.get();//用于吃掉回车,相当于getchar();
    cout<<arr<<endl;
    cin.get(arr,5);
    cout<<arr<<endl;
    system("pause");
    return 0;
输入abcdefghi
输出abcdefghi
输入abcde
输出abcd
cin.getline() // 接受一个字符串,可以接收空格并输出
#include <iostream>
using namespace std;
main ()
char m[20];
cin.getline(m,5); //与上面基本相同。
cout<<m<<endl;
输入:jkljkljkl
输出:jklj
接受5个字符到m中,其中最后一个为'\0',所以只看到4个字符输出;
getline() // 接受一个字符串,可以接收空格并输出,需包含“#include<string>”
#include<iostream>
#include<string>
using namespace std;
main ()
string str;
getline(cin,str);
cout<<str<<endl;
输入:jkljkljkl //VC6中有个bug,需要输入两次回车。
输出:jkljkljkl
输入:jkl jfksldfj jklsjfl
输出:jkl jfksldfj jklsjfl
和cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数
gets()// 接受一个字符串,可以接收空格并输出,需包含“#include<string>
#include<iostream>
#include<string>
using namespace std;
main ()
char m[20];
gets(m); //不能写成m=gets();
cout<<m<<endl;
输入:jkljkljkl
输出:jkljkljkl
输入:jkl jkl jkl
输出:jkl jkl jkl
类似cin.getline()里面的一个例子,gets()同样可以用在多维数组里面:
#include<iostream>
#include<string>
using namespace std;
main ()
char m[3][20];
for(int i=0;i<3;i++)
cout<<"\n请输入第"<<i+1<<"个字符串:"<<endl;
gets(m[i]);
cout<<endl;
for(int j=0;j<3;j++)
cout<<"输出m["<<j<<"]的值:"<<m[j]<<endl;
请输入第1个字符串:
kskr1
请输入第2个字符串:
kskr2
请输入第3个字符串:
kskr3
输出m[0]的值:kskr1
输出m[1]的值:kskr2
输出m[2]的值:kskr3
getchar()//接受一个字符,需包含“#include<string>
#include<iostream>
using namespace std;
main ()
char ch;
ch=getchar(); //不能写成getchar(ch);
cout<<ch<<endl;
输入:jkljkljkl
输出:j


补充:stringstream的使用方法

stringstream类同时可以支持C风格的串流的输入输出操作。
istringstream是由一个string对象构造而来,从一个string对象读取字符。
ostringstream同样是有一个string对象构造而来,向一个string对象插入字符。
stringstream则是用于C++风格的字符串的输入输出的。


#include<iostream>
#include <sstream> 
using namespace std;
int main(){
    string test = "-123 9.87 welcome to, 989, test!";
    istringstream iss;//istringstream提供读 string 的功能
    iss.str(test);//将 string 类型的 test 复制给 iss,返回 void 
    string s;
    cout << "按照空格读取字符串:" << endl;
    while (iss >> s){
        cout << s << endl;//按空格读取string
    cout << "*********************" << endl;
    istringstream strm(test); 
    //创建存储 test 的副本的 stringstream 对象
    int i;
    float f;
    char c;
    char buff[1024];
    strm >> i;
    cout <<"读取int类型:"<< i << endl;
    strm >> f;
    cout <<"读取float类型:"<<f << endl;
    strm >> c;
    cout <<"读取char类型:"<< c << endl;
    strm >> buff;
    cout <<"读取buffer类型:"<< buff << endl;
    strm.ignore(100, ',');
    int j;
    strm >> j;
    cout <<"忽略‘,’读取int类型:"<< j << endl;
    return 0;