C++学习总结2

链接上一篇日志,下面介绍下C++里面的其他内容

补充上一届里面的异常处理代码:

    try
    {
        cout << "try num" << endl;
        throw 1.5;
    }
    catch (double i)
    {
        cout << "catch try num double 1.5" << endl;
        cout << i << endl;
    }

八、结构体与联合体

struct Date
{
    int year;
    int month;
    int day;
};
 
Date catch_today()
{
    Date oneday;
    cin >>oneday.year >> oneday.month >> oneday.day;
    return oneday;
}
 
void show(Date oneday)
{
    cout << oneday.year << "  " << oneday.month << "  "<< oneday.day << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
    Date date = catch_today();
    show(date);
    return 0;
}

     上例中,我们将函数的返回值定义为结构体类型,同时,将结构体传递给一个函数的形参。当然,我们也可以把一个结构体内部的部分变量传递给一个函数,作为它的形参。

结构体与指针:
结构体变量指针,用它来访问它所指向的结构体变量的所有成员。或者说是,结构体指针变量。
使用方法:
  p - >  变量成员。
(*p). 变量成员。
void update (s_time *timer);
调用: update(&system);
结构体与引用 :
结构体类型名 & 引用变量名。
结构体引用变量.成员名。
test _struct &func(test_struct &var);
{};
调用  : k=func(b);
位域:
struct test
{
    unsigned int  a:3;
    unsigned int b:4;
    unsigned int c:5;
    unsigened int d:1;
};
联合体:
union band
{
    int  b1;
    char b2;
    long b3;
};
 

联合体:共有一块内存,其首地址一样。一般用于字节流传输的过程中,进行对齐的时候用。

九、文件

 文件:数据的集合。计算机处理的数据只有以文件的形式存储到磁盘中才能永久的保持下来。
文件的分类:
依据数据的存储格式:文本文件与二进制文件。
文本文件:又称为asc码形式或者字符形式,就是将所有数据当作字符来进行存储。
二进制文件:按照二进制编码来存储数据的方式,主要用来加密。
依据文件的存取方式:顺序文件与随机文件。
顺序文件:只能进行顺序地读取、改写文件中的数据。 有权限命令,w,r。我们一般就是用此。
随机文件: 不管以什么方式打开的文件,都可以写入或者读取文件中的数据。
C++中,不区分随机存取与顺序存取。
文件流:
C++中一般用文件流类来处理文件的输入与输出。
文件流就是 字符流与二进制流。
处理流程:
1、打开一个文件,将一个文件流对象与某个磁盘文件联系起来。(其实这里面还有一个缓冲区的概念,我们先把数据放在缓冲区中,等达到一定数量才将数据写入到磁盘,这样速度更快)
2、使用文件流对象的成员函数,从文件中读取数据,或将数据写入到文件中去。
3、关闭文件,方便别的程序执行相关的操作。
文件流对象:
主要有三类:
输入流 :ifstream
输出流:ofstream  将数据流写入到文件中去,也就是说,这个的视角是文件。。。
输入/输出流:fstream
文件的打开与关闭:
打开文件的作用是在内存中建立文件的各种有关的信息,同时让文件流对象与该文件相关联。
关闭文件的作用是断开文件流对象与文件之间的联系。
1、打开文件
      1)定义流对象,然后将其打开
    ifstream inf;
  ofstream outf;
  fstream iof;
利用成员函数open()打开文件,从而将文件与流联系起来。
inf.open(const char *filename,int  fliemode ,int access);
     2)通过构造函数打开
ofstream outf(const char *filename,int filemode,int access);
其中,filename是我们准备打开文件的名称,也可以是路径名称,如c:\data\data.dat
filemode 是打开的模式。
ios::in  按照读的方式打开文件。ios ::out 按照写的方式打开文件。 ios::app 按照追加的方式打开文件。ios::binary按照二进制方式存取文件
包含头文件 《fstream》
这个头文件中包含了以上三个类,ifstream  ofstream iostream 。他们是从istream ostream iofstream 派生而来,而此三个,也是从ios派生来的,所以,ifstream  ofstream iofstream可以访问ios所定义的所有操作。
acces 属性列表:
0:普通文件
1:只读文件
2:隐含文件
4:系统文件
8:备份文件
  3)判断文件是否打开
ifstream file1("d:\file.dat");
if(!file1) //file1.fail()
{
   cout << "打开文件失败"<<endl;
}
2、关闭文件
close();
outf.close();
文件流成员函数:
几个常用 的成员函数介绍:
read() ,write()
此函数是用来读写二进制文件的。
open()把没有初始化的对象与文件关联起来。
put() 输出流,输出单个字符。
eof() 用于判断是否达到了文件末尾
ignore(20,“ ”)读取了20个字符并忽略空格。
peek()获取输入流中的下一个字符。
flush()刷新流 ,这个好处是为了防止数据丢失。因为我们再执行输出操作时候,数据先存在一个缓冲区当中,然后当其满的时候,才会写到磁盘上,所以,需要时常刷新操作,然后将数据写进磁盘中。
ofstream类
   主要是将流数据写入到磁盘文件中,我们可以使用它来创建一个新文件,并且将数据写入到一个现有文件中。也可以追加一部分数据到文件中去。
ofstream outfile("example.txt");
outfile << "this is a ";
ofstream outfile("example.txt",ios::app);
outfile << "this is b";
1、追加文件
#include <iostream>
#include <fsteam>
using namespace std;
int main()
{
    cout << "打开输出流文件"<<endl;
    ofstream outfile("example.txt",ios::app);
   if(!outfile.fail())
    {
        cout<<“追加到”<<endl;
        outfile << ", i  think !";
    }
else
       cout << "无法打开文件" << endl;
    return 0;
}
ifsream类
从磁盘文件中读取数据。
输入流对象,读取数据。
文件随机访问
对于文件的随机访问,一般先找到那个要读写的位置,然后在调用文件读写函数读出或者写入数据。
实例:将2-200之间的偶数写入到一个二进制文件中,同时读取10-19之间的十个偶数。

int i,j;
 ofstream outfile("test1.dat",ios::binary| ios::out);
   if(outfile.fail())
  cout << "打开文件失败"<<endl;
   for(i=2;i<200;i+=2)
  outfile.write((char* )&i,sizeof(int));
  outfile.close();
ifstream infile("test1.dat",ios::binary|ios::in);
if(infile.fail())
  cout << "打开文件失败"<<endl;
infile.seekg(20*sizeof(int));//移动文件夹指针    与之对应的还有seekp,主要用来定位之用
for(i=0;i<10&&infile.eof();i++)
 {
     infile.read((char*)&j,sizeof(int));
    cout << j <<endl;
} 
 infile.close();

解析形如: 116.111,120,2344,22222   一行行的文件  文本文件

DWORD WINAPI ChildFunc1(LPVOID p)
{
    
    ifstream fin("read.txt");
    string line,temp; //line每一行的数据量,temp为临时加载的数据
    HANDLE hEvent;
    hEvent = OpenEventW(EVENT_ALL_ACCESS,FALSE,_T("ChildEvent1"));
    int countnum = 0;
    while(getline(fin,line))//文件没到结尾
    {

        countnum ++ ;
        if (countnum == 4)
        {
            countnum = 0;

        //八线激光雷达两帧为一周期
            if (recvcount1 == 6)
            {
                recvcount1 = 0;
            }
        int strnum = 0;
        for (int i = 0; i < line.size(); ++i)
        {
            if (line[i] == ',' )
            {
                stringstream stream;
                stream << temp;//temp需要清零
                switch(strnum)
                {
                    case 0: stream >> szBuffer1[recvcount1].lon;stream.str("");temp = "";break;
                    case 1: stream >> szBuffer1[recvcount1].lat;stream.str("");temp = "";break;
                    case 2: stream >> szBuffer1[recvcount1].speed;stream.str("");temp = "";break;
                    default:break;
                }
              strnum++;
            }
            else
            {
               temp += line[i];
            }
            if (i == line.size()-1)
            {
                stringstream stream;
                stream << temp;//temp需要清零
                stream >> szBuffer1[recvcount1].pathAngle;
                stream.str("");
                temp = "";
            }            
        }
        cout << "flag1:  "<<recvcount1<<endl;
        recvcount1++;
        SetEvent(hEvent);
        Sleep(200);
      }
    }
    return 0;
}
 

解析二进制文件:读取某一个结构体

DWORD WINAPI ChildFunc(LPVOID p)
{
    FILE *infile = fopen("data.txt","rb"); 
    long i = 0;
 
    HANDLE hEvent;
    hEvent = OpenEventW(EVENT_ALL_ACCESS,FALSE,_T("ChildEvent"));
 
    while(!feof(infile))//文件没到结尾
    {
        //八线激光雷达两帧为一周期
        fseek(infile,i*sizeof(KEYPOINT),SEEK_SET);//从文件的开头开始算偏移
//连续读取,这里面的fseek都可以不需要用,OK
//编程最难的就是逻辑。逻辑弄好,一切OK
        ++i;
        fread(&szBuffer[recvcount],sizeof(KEYPOINT),1,infile);//每次读一帧  
        cout << "flag:  "<<recvcount<<endl;
        recvcount++;
        if (recvcount == 6)
        {
            recvcount = 0;
        }
        SetEvent(hEvent);
        Sleep(80);
    }
    return 0;
}

主要是定位麻烦,fseek函数的使用,连续读取

原文地址:https://www.cnblogs.com/zhuxuekui/p/3903525.html