C++程序笔记——I/O流

一、输入输出流的插入和提取运算符

题目描述

首先建立文本文件digit.txt,然后向文件写入个以空格分开的数字字符,最后再将10个字符从文件上读出到屏幕上

C++代码实现

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    
    
    //opent the file with way writing
    fstream testfile("file.txt",ios::out | ios::in);
    if(!testfile.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
        return 0;
    }

    //start to write
    for(int i = 0; i <10;i ++)
    {
    
    
        testfile<<i<<endl;
    }

	//start to read the information
    int num;
    testfile>>num;
    cout<<num;
    while(!testfile.eof())
    {
    
    
        cout<<num<<" ";
        testfile>>num;
    }
    cout<<endl;
    
    testfile.close();
    return 0;
}

实际运行结果

在这里插入图片描述

问题分析
  • 打开失败,“ios::out ”不是说明文件不存在会自动创建吗?虽然“ios::in”要求文件必须存在。最终妥协了,既然整合了,还是一个文件必须存在为基础
修改
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    
    
    //opent the file with way writing
    fstream testfile("file.txt",ios::out);
    if(!testfile.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
        return 0;
    }

    //start to write
    for(int i = 0; i <10;i ++)
    {
    
    
        testfile<<i<<endl;
    }
    testfile.close();
    fstream infile("file.txt",ios::in);
    int num;
    infile>>num;
    while(!infile.eof())
    {
    
    
        cout<<num<<" ";
        infile>>num;
    }
    cout<<endl;
    infile.close();
    return 0;
}

在这里插入图片描述

分析与总结
  • 写入的时候明明指明的是数字与数字之间是以换行符为分割的,但是读入的时候,就啥都没了。
  • ">> " 读入的时候,会自动忽略换行、空格、制表等空白字符

偶然间的困惑,我想去证明

1、一个IO流对象打开时制定了读写两种方式,会有两个指针
  • 即使指定文件的打开方式为“ios::in | ios::out”,写已经到达了尾指针,如果还继续输出,那就移动指针到文件的头部,继续输出
  • 证明如下:
    • 注意:这里的文件已经提前创建过了
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    
    
    //opent the file with way writing
    fstream testfile("file.txt",ios::out|ios::in);
    if(!testfile.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
        return 0;
    }

    //start to write
    for(int i = 0; i <10;i ++)
    {
    
    
        testfile<<i<<endl;
    }
    int num;
    testfile>>num;
    if(!testfile.eof())
    {
    
    
        cout<<"two pointers"<<endl;
        cout<<num<<" ";
        testfile>>num;
    }
    else
    {
    
    
        cout<<"only one pointer!"<<endl;
    }
    cout<<endl;
    testfile.close();
    return 0;
}

在这里插入图片描述

分析
  • 这里将读写两个模式综合到一块,该文件指针同时是读指针也是写指针,将内容写完之后,写指针自动的在文件的末尾,然后再开始读。
    • 如果可以读出来,那就说明有两个的指针
    • 如果读不出来,就说明读写指针是同一个指针,同时到达末尾
移动指针后

在这里插入图片描述

  • 运行结果
    在这里插入图片描述

二、get函数和put函数

get()函数
  • 用于从输入设备中获取一个字符型数据
  • 特点:可以读取任何类型的数据,包括空格、回车、制表符等空白字符
  • 函数类型
    • 有参函数get(char ch):
      • 将获取到的字符保存到对应的ch中
      • 返回值为bool型,如果读取成功,就返回true;如果读取失败,就返回false
    • 无参函数get():
      • 将读取的字符型数值作为返回值返回,char ch = get()
程序实例一——可以读取任何类型的数据
#include <iostream>

using namespace std;

int main()
{
    
    
    //4-4
    int n = 0;
    char ch;
    cout<<"please input some chars ,ending with enter!"<<endl;
    while((ch = cin.get())!= '\n')
    {
    
    
        cout<<ch;
        n ++;
    }
    cout<<endl;
    cout<<"the number od the chars is "<<n<<endl;
    cout << "Hello world!" << endl;
    return 0;
}

在这里插入图片描述
无参版本

#include <iostream>

using namespace std;

int main()
{
    
    
    //4-4
    int n = 0;
    char ch;
    cout<<"please input some chars ,ending with enter!"<<endl;
    while(1)
    {
    
    
        cin.get(ch);
        if(ch == '\n')
        {
    
    
            break;
        }
        cout<<ch;
        n ++;
    }
    cout<<endl;
    cout<<"the number od the chars is "<<n<<endl;
    cout << "Hello world!" << endl;
    return 0;
}
程序实例二——文件类读入和读出
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
    
    
    int n1 = 0;
    char ch1;
    fstream outfile("filetest.txt",ios::out);
    outfile<<"Microsoft\nVisual\nC++";
    outfile.close();

    fstream infile("filetest.txt",ios::in);
    while(!infile.eof())
    {
    
    
        ch1 = infile.get();
        cout<<ch1;
        n1 ++;
    }
    cout<<endl;
    cout<<"the numnber of the characters of the file is "<<n1<<endl;
    infile.close();

	return 0;
}
分析总结
  • 使用get函数逐个读取字符,可以很好的根据输入的结果进行的判定程序的是否进行读取
  • 判定是否已经到达文件的末尾的方式
    • 使用无参函数,(ch = in.get()) == EOF; 判定是否等于EOF,默认的文件输出的末尾
    • 使用有参函数,if(in.get(ch)),到达文件的末尾一定数读取失败,返回值为false
put()函数
知识点
  • 用于输出单个字符型的数据
  • 特点:
    • 返回类型:是指向的该函数输出流对象。便于连续调用进行输出
    • 对<<的重定义方式为:outstream& operator<<(char)

在这里插入图片描述

输入流的getline()函数

基本介绍

C++实例实现

标准输入和输出

#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

int main()
{
    
    
    int len , maxlen = 0;
    char s[8],t[8];
    cout<<"please input some arrays of characters:"<<endl;
    while(cin.getline(s,8))
    {
    
    
        len = (int)strlen(s);
        if(len>maxlen)
        {
    
    
            maxlen = len;
            strcpy(t,s);
        }
    }
    cout<<endl;
    cout<<"the longest array of the characters is:"<<t<<endl;
    cout<<"the length is "<<maxlen<<endl;
    return 0;
}

在这里插入图片描述

  • 文件输入和输出
#include <iostream>
#include <fstream>
#include <string.h>

using namespace std;

int main()
{
    
    
    int len, maxlen = 0;
    char s[80],t[90];
    fstream outfile;
    outfile.open("filetest1.txt",ios::out);
    if(!outfile.is_open())
    {
    
    
        cout<<"open the file with writing is wrong!"<<endl;
        return 0;
    }
    outfile<<"Windows Xp"<<endl;
    outfile<<"Visual Studio "<<endl;
    outfile<<"Microsoft Office"<<endl;
    outfile.close();
    fstream infile("filetest1.txt",ios::in);
    if(!infile.is_open())
    {
    
    
        cout<<"reading the file error!"<<endl;
        return 0;
    }
    while(infile.getline(s,sizeof(s)))
    {
    
    
        len = (int)strlen(s);
        if(len>maxlen)
        {
    
    
            maxlen = len;
            strcpy(t,s);
        }
    }
    cout<<"the longest array of characters is:"<<t<<endl;
    cout<<"the length of the array is:"<<maxlen<<endl;
    infile.close();
    return 0;

在这里插入图片描述

write函数

功能描述

  • 向输出设备输出指定个数的多个字符的操作
  • out.write(字符型的指针,字节数);
    • 返回类型:io流的具体的对象,可以连续的调用
    • 参数列表:注意第一个参数是字符型指针,要进行强制类型转换

C++代码相关实验

文本输入和二进制输入的方式对比
#include <iostream>
#include <string.h>
#include <fstream>

using namespace std;

int main()
{
    
    
    int a = 123445;
    fstream outascii("file.txt",ios::out);
    fstream outbinary("file2.txt",ios::out | ios::binary);
    outascii<<a;
    outbinary.write((char*)&a,sizeof(a));
    outascii.close();
    outbinary.close();
    return 0;
 }

在这里插入图片描述

分析与总结
  • 采用二进制进行数据保存,是将数据按照在内存中的保存形式进行保存。“int a = 1;”整型数据a占用四个字节,1翻译成32位的数据“0000 0000 0000 0000 0000 0000 0001”,保存到对应内存中
  • 采用文本表示,会将的1按照ASCII码表进行的转换,转成对应的数字进行保存。程序中是5个数字,总共占用5个char型的内存空间,5个字节

read函数

功能描述

  • 功能:用于获取多个字符的输出

  • 使用:in.read(字符型指针,字符个数); 从输入设备中读取n个字符,存入到字符型指针所指的内存空间中

    • 返回值:bool型,读取失败,返回false,读取成功,返回true
  • 注意: *如果是以二进制文件的方式进行的输入,要写入对应的数据的内存中,大小为该数据的所占用的内存空间大小

C++相关实验的代码

  • 从标准输入和输出中读取相关的数据
int main()
{
    
    
    char *ch = new char[8];
    cin.read(ch,7);
    cout<<ch<<endl;
    return 0;
}

在这里插入图片描述

  • 从文件中读取相关的数据
int main()
{
    
    
    char *ch = new char[8];
    fstream infile("file.txt",ios::in);
    if(!infile.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
    }
    infile.read(ch,4);
    cout<<ch<<endl;
    infile.close();
    return 0}

在这里插入图片描述

分析总结
  • read函数是可以读取空白字符地,其返回地特定数量的单个字符,不是字符串,末尾不会加上’\0’
  • 其第一个参数是字符型地址,如果要将一个二进制文件写入其中,需要将地址进行强制类型转换。将数据写入到特定的内存空间中

write和read函数的总结

知识点
  • read和write函数一般结合使用,进行二进制文件的读/写
  • 使用write()函数生成二进制文件中的数据
  • 使用read()函数来读取二进制文件中的数据
C++程序实例一
  • 先向二进制文件中写入整型数据1~10,再将10个数据从文件读出并输出到屏幕上
#include <iostream>
#include <string.h>
#include <fstream>

using namespace std;

int main()
{
    
    
    //write ten number in the memory!
    fstream outbin("binary.txt",ios::out|ios::binary);
    if(!outbin.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
        return 0;
    }
    for(int i = 1;i < 11;i ++)
    {
    
    
        outbin.write((char*)&i,sizeof(i));
    }
    outbin.close();

    //read the data from the memory
    fstream inbin("binary.txt",ios::in|ios::binary);
    if(!inbin.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
    }
    //problem:how to read one num or all num?
    for(int i = 0;i < 10;i ++)
    {
    
    
        inbin.read((char*)&i,sizeof(4));
        cout<<i<<endl;
    }
    return 0;
 }
分析与总结
  • 最后的从文件中读入数据,直接根据返回值判定是否已经读取完毕,毕竟计数不是很方便

在这里插入图片描述

C++程序实例二
  • 首先将3名学生的学号、姓名和成绩写入二进制文件studentinfo.dat中,然后在将该文件中的数据读到结构体数组中,并将其输出到屏幕上
#include <iostream>
#include <string.h>
#include <fstream>

using namespace std;

typedef struct Student
{
    
    
  char num[10];
  char name[20];
  int score;
};

int main()
{
    
    
    //write the data into the file
    Student stu[3] = {
    
    
    {
    
    "1210101","gray",618},
    {
    
    "1608205","linux",746},
    {
    
    "1564789","installman",789}
    };
    fstream outfile("studentinfo.txt",ios::out | ios::binary);
    if(!outfile.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
        return 0;
    }
    for(int i = 0;i < 3; i++)
    {
    
    
        outfile.write((char*)&stu[i],sizeof(stu[i]));
        cout<<"import the data triumphantly!"<<endl;
    }
    outfile.close();
    cout<<"complete the importation of the data!"<<'\n'<<endl;

    //read the data from the file
    Student stu1[3];
    fstream infile("studentinfo.txt",ios::in|ios::binary);
    if(!infile.is_open())
    {
    
    
        cout<<"open the file abortively !"<<endl;
        return 0;
    }
    int i = 0;
    while(infile.read((char*)&stu1[i],sizeof(stu1[i])))
    {
    
    
        cout<<"name:"<<stu1[i].name<<endl;
        cout<<"num:"<<stu1[i].num<<endl;
        cout<<"score:"<<stu1[i].score<<endl;
        cout<<endl;
        i ++;
    }
    infile.close();
    return 0;
}

在这里插入图片描述

分析与总结
  • 注意,当我们以二进制直接写入文件地时候,是可以直接以一个完整的文件为单位进行读出和写入的,没有必要一个一个的单独写入。但是要注意将之转换成的对应的字符指针型的数据格式

在这里插入图片描述

文件随机读写概述和相关函数

知识点
  • 通过非顺序地移动指针实现对文件地随机读写

  • seekg和seekp
    在这里插入图片描述

  • tellg和tellp
    在这里插入图片描述

文件随机读写的实例
  • 描述:将三名学生的学号、姓名和成绩写入二进制文件studentinfo.txt中,再将第二名学生的成绩改为627,最后从文件中读取第num个元素(用户从键盘上获取对应的输入)信息并将其输入到屏幕上
#include <iostream>
#include <string.h>
#include <fstream>

using namespace std;

typedef struct Student
{
    
    
  char num[10];
  char name[20];
  int score;
};

int main()
{
    
    
    //write the data into the file
    Student stu[3] = {
    
    
    {
    
    "1210101","gray",618},
    {
    
    "1210102","linux",746},
    {
    
    "1210103","installman",789}
    };
    fstream outfile("studentinfo.txt",ios::out | ios::binary);
    if(!outfile.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
        return 0;
    }
    for(int i = 0;i < 3; i++)
    {
    
    
        outfile.write((char*)&stu[i],sizeof(stu[i]));
        cout<<"import the data triumphantly!"<<endl;
    }
    outfile.close();
    cout<<"complete the importation of the data!"<<'\n'<<endl;

    
    //read the data from the file
    Student stu1[3];
    fstream infile("studentinfo.txt",ios::in|ios::binary|ios::out);
    if(!infile.is_open())
    {
    
    
        cout<<"open the file abortively !"<<endl;
        return 0;
    }
    stu[1].score = 627;
    //move the pointer of the file out stream to the position of the second element
    infile.seekp(1*sizeof(Student),ios::beg);
    //rewrite the data to the same position.Cover the old one!
    infile.write((char*)&stu[1],sizeof(Student));
    infile.close();


    //test whether write the message into the file!
    int num;
    cout<<"the number of the student you want to check!"<<endl;
    cin>>num;
    if(num>3|num<1)
    {
    
    
        cout<<"the student you want to check is inexistence!"<<endl;
        return 0;
    }

    
    //open the file to show the message of the student!
    fstream infile1("studentinfo.txt",ios::in|ios::binary);
    if(!infile1.is_open())
    {
    
    
        cout<<"open the file abortively!"<<endl;
        return 0;
    }
    Student test;
    //move the pointer of the file to the correct position!
    infile1.seekg((num - 1)*sizeof(Student),ios::beg);
    //read the information of the appointed student
    infile1.read((char*)&test,sizeof(Student));
    cout<<"No:"<<num<<"student:"<<endl;
    cout<<"no:"<<test.num<<endl;
    cout<<"name:"<<test.name<<endl;
    cout<<"score:"<<test.score<<endl;
    infile1.close();

   return 0;
}

在这里插入图片描述

分析与总结
  • 一般不在文件中的进行非顺序的插入和移动指针操作,因为比较耗时

自定义类型数据的标准输入输出和文本文件的输出输入

概述
  • 通过对"<<“和”>>"的运算符重载,实现用户可以通过调用直接输出自定义类型的数据
  • 注意上述的两个运算符是双目运算符,需要两个参数,一个是调用该函数的输入和输出流,一个数需要输出的数据
程序实例
typedef struct Student
{
    
    
  char num[10];
  char name[20];
  int score;
};

//the overload of <<
ostream& operator<<(ostream& out,Student stu)
{
    
    
    out<<"name:"<<stu.name<<endl;
    out<<"num:"<<stu.num<<endl;
    out<<"score:"<<stu.score<<endl;
    return out;
}

//the overload of >>
istream& operator>>(istream& in,Student stu)
{
    
    
    in>>stu.num>>stu.name>>stu.score;
    return in;
}
  • 剩余部分参见之前的代码

猜你喜欢

转载自blog.csdn.net/Blackoutdragon/article/details/108881764