zoukankan      html  css  js  c++  java
  • C++单元小结之Vector与迭代器(续),内置数组、vector和string,文件数据处理(文件操作续),字符串流(续)

    C++单元小结

    Vector(续)

    vector的用法:
    vector是长度可变的向量,可替代内置数组,更灵活,更高效。
    要使用vector,必须包含头文件
    定义vector时必须指定元素的类型,格式为:
    vector<元素类型> 变量名;
    定义的同时可以初始化vector对象。
    下面是几种常见的初始化方法:
    在这里插入图片描述

    //拷贝初始化
    vector<int>  ivec2(ivec);		// 把ivec的元素复制给ivec2
    vector<int>  ivec3 = ivec;		// 把ivec的元素复制给ivec3
    

    这时拷贝的vector元素的数据类型必须一致,否则出现错误。另外列表进行初始化时,必须使用大括号,小括号则显示错误。
    在使用时我们需要注意容易混淆的问题:各种括号

    vector<int> v1(10);//v1有10个int元素,每个都初始化为0
    vector<int> v2{10}; //v2有1个元素,值是10
    vector<int> v3[10]; //v3是有10个元素的数组
    				//每个元素都是一个空vector对象
    vector<int> v4(10, 1); //v4有10个int元素,每个都初始化为1
    vector<int> v5{10, 1}; //v5有2个int元素,值分别是10和1
    

    vector支持的操作:
    在这里插入图片描述
    注意事项:
    如果要用循环向vector对象中添加元素,不能使用范围for,范围for不能改变所遍历的容器的大小
    不能用下标运算符向vector中添加元素
    下标运算符只能访问已经存在的元素

    迭代器(续)

    迭代器类似于指针类型,提供对对象的间接访问
    迭代器在容器或string对象上使用,指向的对象是容器中的元素或string中的字符
    访问标准容器的元素的通用方法是使用迭代器
    使用迭代器可以访问容器中的某个元素,也可以在容器上移动
    标准库容器迭代器的类型
    iterator、const_iterator
    cbegin()和cend()函数返回const_iterator
    //cbegin/cend直接返回const_iterator,无论容器是否是const的,例:
    auto it3 = v.cbegin();
    //it3类型是vector::const_iterator

    内置数组、vector和string:

    使用vector和string的代码比使用内置数组和字符数组更简洁、更高效
    string和vector都是可变长度的
    灵活,编写相应的代码比使用动态内存管理更容易且不易出错
    string和vector是对象
    封装带来的简单性,对接口编程
    虽然不知道string类和vector类型具体是如何实现的,但是并不妨碍正确地使用它们

    文件数据处理

    文件读写——输入输出重定向

    将标准输入和标准输出与命名文件关联起来
    c:> program outputfile
    运行名为program.exe的可执行程序,用文件inputfile作为输入,用文件outputfile作为输出

    文件读写——标准库文件流

    C++标准库中的文件流:使用文件流要包含头文件
    ifstream类:用来输入(读文件)的文件流
    ofstream类:用来输出(写文件)的文件流
    fstream类:把文件连接到流对象用来输入和输出
    istream(ostream、iostream)的操作在ifstream(ofstream、fstream)中都可以使用

    文件操作的步骤

    (1)新建一个文件流对象
    读文件用ifstream,写文件用ofstream;
    (2)把文件流对象和文件关联起来
    打开文件,使用文件流的open函数;
    可以指定打开文件的模式
    (3)操作文件流
    使用与终端I/O相同的操作读写文件
    (4)关闭文件流
    使用文件流的close函数
    例:

    #include <fstream>		//文件流标准库头文件
    using namespace std;
    int main(){
    	ifstream in("numbers.txt");
    	int number, sum = 0;
    	in >> number;
    	while(number != 0){
    		sum += number;
    		in >> number;
    	}
    	in.close();
    	ofstream out;
    	out.open("output.txt");	
    	out << "sum is: " << sum << endl;
    	out.close();
    }
    

    具体实例:
    插入文件(将文件2中的数据插入到1中):

    #include<cstdio>
    #include<iostream>
    using namespace std;
    void append(FILE*,FILE*);
    int main()
    {
        FILE*f1,*f2;
        char *fname1="data1.txt";
        char *fname2="data2.txt";
        f1=fopen(fname1,"a+");
        f2=fopen(fname2,"r");
        append(f1,f2);
        fclose(f1);
        fclose(f2);
        printf("DONE.
    ");
    }
    void append(FILE*f1,FILE*f2)
    {
        char c;
        fseek(f1,0,2);
        while((c=getc(f2))!=EOF)
        putc(c,f1);
    }
    
    

    复制文件:

    #include<stdio.h>
    void fcopy(FILE*,FILE*);
    int main(void)
    {
        FILE*f1,*f2;
        f1=fopen("1.txt","r");
        f2=fopen("2.txt","w");
        fcopy(f1,f2);
        fclose(f1);
        fclose(f2);
    }
    void fcopy(FILE*f1,FILE*f2)
    {
        char c;
        while((c=getc(f1))!=EOF)
        putc(c,f2);
    }
    
    

    这里对于int main(),int main(void)与void main()的区别如下:

    #include<stdio.h>
    void main(){
    }
    #include<stdio.h>
    int main(void){
    return 0;
    }
    void main() 这么定义只是说明main函数没有返回值
    int main(void)和int main()是一样的,括号里没有东西就相当于void,
    只是说明main函数有一个int类型的返回值

    C语言的规范里面要求main函数需要返回一个int类型的返回值来告诉操作系统这个程序是执行正确还是执行错误。执行正确返回0,执行错误返回非0。但是目前操作系统都不去判断这个返回值,所以写成void main()还是int main()其实是一样的,没有什么区别。不过既然有规范,还是推荐写成int main()这种形式。(C++里不支持void main()这种形式,只能写成int main()。)

    字符串流(续)

    字符串流用于内存I/O,即在字符串上进行I/O操作
    istringstream:从string对象中读取数据
    ostringstream:向string对象写入格式化的内容
    stringstream:从字符串读取数据,将数据写入字符串

    使用时包含标准库头文件
    在定义时直接用string对象初始化
    strm.str(s),将字符串s复制到字符串流strm中,返回void
    strm.str(),返回字符串流strm中保存的字符串的副本

    字符串流的用途:
    输入缓冲区
    从输入流一次性读取一大块数据,以字符串形式保存在istringstream对象中,再用适当的输入操作逐项从istringstream对象中提取各个数据项
    输出格式化
    将所有要输出的内容先用输出操作写到ostringstream对象上,再一次性的将这个ostringstream对象中保存的字符串写入输出流

    例:读取文件中的学生成绩记录,统计并将结果输出到另一个文件

    最终程序中应用了C++的结构体、string、vector、迭代器、文件流、字符串流等类型:

    //利用istringstream,读取并处理一行学生记录的代码
    //从输入文件流in中读一行学生成绩并存入scoreSheet中
    ScoreItem item;	
    string buffer;				
    getline(in, buffer);	
    istringstream is(buffer);	
    is >> item.name;
    int score;
    while(is >> score)
    	item.scores.push_back(score);
    scoreSheet.push_back(item);
    //利用ostringstream构造并输出一个学生的统计信息的代码
    //处理scoreSheet中的一个元素,即一个学生的记录
    ostringstream format("");	
    format << (it -> name) << " ";	
    //按格式将数据继续写入format
    format.precision(1);		//小数点后保留1位
    format << sum << " " 
    		<< courseNumber << " " 
    		<< fixed << average;
    //构造的输出信息格式为:姓名 总成绩 课程门数 平均成绩
    out << format.str() << endl;	
    				//一次性写入输出文件流out中
    

    从该程序中,我们可以利用复合类型,根据实际应用中的问题定义恰当的数据结构。
    因此合理地利用标准库提供的类型,可以使编程更简便、更高效。

  • 相关阅读:
    OLED的相关信息
    FilterDispatcher is depredated!plesae use the new filters
    lua c函数注册器
    一个简易版本的lua debugger实现
    【Unity Shaders】Using Textures for Effects——让sprite sheets动起来
    GDAL库中WFS服务中含有中文不能获取数据的问题
    golang:使用timingwheel进行大量ticker的优化
    扩展GDAL,支持CNSDTF格式(一)
    理解WebKit和Chromium: Android 4.4 上的Chromium WebView
    学习tornado:异步
  • 原文地址:https://www.cnblogs.com/study-hard-forever/p/12130030.html
Copyright © 2011-2022 走看看