首页 > 编程语言 >使用C++实现Modbus CRC16检验相关内容

使用C++实现Modbus CRC16检验相关内容

时间:2023-02-24 00:13:22浏览次数:44  
标签:false CRC16 int C++ Modbus crc SerialInterface 串口 return

使用C++实现Modbus CRC16检验相关内容

Modbus CRC-16 校验代码

以下为Modbus CRC-16校验代码函数:

  1. 其中参数int* crc_sum为校验返回值,分为两个字节;
  2. 参数int* data_blk_ptr为校验数据帧缓存数组;
  3. 参数int data_blk_size为数据帧除去CRC校验位的剩余长度,一般为(数据帧长度 - 2)
/*--------------------------------------------------------------------*/
/**
  * function: Modbus CRC16(LSB-MSB) calculation
  * update in 2022/03/17
  *   input paramenter: 
  *         data_blk_ptr: inital address of waiting calculation data, 
  *         usDataLen: length of data frame
  *   output parameter:
  *         crc_sum: CRC16-modbus results' inital address
  *   returned value:
  *         checked result - TRUE or FALSE (bool)   
  */
void update_crc(int* crc_sum, int *data_blk_ptr, int data_blk_size)
{
      unsigned int i;
      unsigned short crc = 0xFFFF;
      unsigned short crcl;

      while(data_blk_size--){
            crc ^= *data_blk_ptr++;
            for (i = 0; i < 8; ++i){
                  if (crc & 1)
                        crc = (crc >> 1) ^ 0xA001;
                  else
                        crc = (crc >> 1);
            }
      }
      crcl = crc;
      crc_sum[1] = (unsigned char)(crc>>8);
      crc_sum[0] = (unsigned char)(crcl);
}

C++中将ASCII码转换为INT数据类型代码

int byte_2_str(char charvalue) { 
   int value;
   if((charvalue >= 48) && (charvalue <=57)){
    value = (int)charvalue - 48;
   }
   else if((charvalue >= 65) && (charvalue <=70)){
    value = (int)charvalue - 55;
   }
   return value;

} 

C++中打开串口代码

本段代码依赖的头文件和元未见分别为:SerialInterface.h和SerialInterface.cpp,两个文件代码在附录中全部给出。

SerialInterface com;
int SerialInit(){
    // com.setBufferSize(1000000,1000000);
    if(!com.openSyn("COM3", 38400, NOPARITY,8, ONESTOPBIT))
    {
        cout << com.getSerialLastError() << endl;
        getchar();
        return 0;
    }
    return 1;
    
}

CRC校验逻辑

  1. 在使用串口接受或发送的数据帧存储到***.txt文件中,通过ofstream和ifstream打开两个txt文件,并将无效信息过滤掉,存储到新的txt文件中;
  2. 在原始的txt文件中读取并存储到新的txt文件中的信息,是以String的形式存储的,在使用CRC校验时,需要将txt文件中的String数据转换为16进制数据,并存储到新的数据帧缓存中;
  3. 通过对新的数据帧缓存中的数据进行CRC-16 modbus校验,并对比数据帧的校验数据和新计算的校验数据,输出校验结果,具体实现代码如下:
int main(){
    string s;
    ofstream outf;
    ifstream inf;
    int totalCount = 0;
    int crcckcount = 0;
    SerialInit();
    // //移除时间戳
    inf.open("./XXX.txt");  //此处需要打开存储数据的原始txt文件名称,包含文件格式       
    //打开输出文件
    outf.open("./removetimestamp.txt"); //此处需要打开用于存储过滤无效信息后的txt文件名称,包含文件格式        
    while (getline(inf, s))   //getline 用于获取整行内容,并存储与String s中  
    {
        if(s.length() >=77){
            outf << s << '\n'; //将过滤后的String存储到新的txt文件中
            totalCount++;
        }
        cout << s << endl; //cmd窗口数据结果,用于观察
    }
    cout<<"the number of effective frame: "<<totalCount<<endl; // cmd窗口输出过滤得到的有效数据帧数量
    
    inf.close(); //关闭原始数据txt文件
    outf.close(); //关闭过滤数据txt文件
    //移除时间戳结束
    system("pause");

    /*********************开始进行数据处理*************************/
    cout<<"data processing Running..."<<endl;
    crcckcount = 0;
    inf.open("./removetimestamp.txt");   //打开存储过滤后数据的txt文件
    outf.open("./result.txt");  //创建用于存储16进制数据的txt文件
    string hexS;
    char hexCharqrray[52];
    char* pchar = hexCharqrray;
    totalCount = 0;
    while (getline(inf, hexS))     
    {
        int charcount = 0;
        if(hexS.length() >=FRAME_LEN*3-1){
            // outf << hexS << '\n';
            for(int i = 0; i <78; i++){
                    cwFlag = i%3; 
                    switch(cwFlag){
                        case 0:{
                            tempdat[0] = byte_2_str(hexS[i]);
                        }break;
                        case 1:{
                            tempdat[1] = byte_2_str(hexS[i]);

                        }break;
                        case 2:{
                            if(charcount < FRAME_LEN){
                                framebuffer[charcount] = tempdat[0]*16+ tempdat[1];
                                charcount++;  
                            }
                            
                        }break;
                        default:break;
                    }

                    // pchar[charcount] = hexS[i];
                    
                    
            }
            cout<<endl;
            totalCount++;
        }
        else{
            cout<<"Error: the length of this line is: "<<hexS.length()<<endl;
        }
        
        cout <<"String result: "<< hexS << endl;
        cout<<"Converted Value: ";
        for(uint16_t i = 0; i < FRAME_LEN; i++){
            cout<<"0X"<<hex<<framebuffer[i]<<", ";
            outf<<"0X"<<hex<<framebuffer[i]<<", ";
            serialbuffer[i] = framebuffer[i];
            
        }
        /*************check CRC16 modbus****************/
        // system("pause");
        cout<<"CRC check biginning: "<<endl;
        update_crc(crcckrst, framebuffer, FRAME_LEN - 2);
        if((crcckrst[0] == framebuffer[24])&&(crcckrst[1] == framebuffer[25])){
            cout<<"The "<<dec<< totalCount <<"th line CRC check result is PASS."<<endl;
            crcckcount++;
        }
        else{
            cout<<"The "<<dec<< totalCount <<"th line CRC check result is FAIL."<<endl;
            cout<<"crcckrst[0] "<<crcckrst[0] <<"crcckrst[1]"<<crcckrst[1]<<"framebuffer[24]"<<framebuffer[24]<<"framebuffer[25]"<<framebuffer[25]<<endl;
        }
        
        // serial sending data 
        com.writeData(serialbuffer,FRAME_LEN);
        Sleep(25); //用于降低串口发送数据频率
        outf <<endl;
        cout<<endl;
    }
    //close serial port
    com.closeComm();
    // close txt files
    inf.close();
    outf.close();

    cout<<"data processing end..."<<endl;
    cout<<"Totally, "<<totalCount<<" frames was converted."<<endl;
    cout<<"Totally, "<<crcckcount<<" frames CRC16 check PASSED"<<endl;
    cout<<"Totally, "<<(totalCount - crcckcount) <<" frames CRC check FAILED."<<endl;

    return 0;
}

附录

CRC16-modbus.cpp 文件内容


//实现txt文件的读入并重写入另外一个txt文件中~
#include<fstream>  //ifstream
#include<iostream>
#include<cstring>     //包含getline()

#include <cstdlib>
#include "SerialInterface.h"
#include "SerialInterface.cpp"
#include <windows.h>
#include <tchar.h>
// #include "CRC16.h"
//#include<cmath>
using namespace std;
#define FRAME_LEN 26
#define CRC_LEN 2

SerialInterface com;

int tempdat[3];
int hexdat;
int cwFlag = 0;
int framebuffer[26];
char serialbuffer[26];
int crcckrst[2];

int byte_2_str(char charvalue) { 
   int value;
   if((charvalue >= 48) && (charvalue <=57)){
    value = (int)charvalue - 48;
   }
   else if((charvalue >= 65) && (charvalue <=70)){
    value = (int)charvalue - 55;
   }
   return value;

} 

/*--------------------------------------------------------------------*/
/**
  * function: Modbus CRC16(LSB-MSB) calculation
  * update in 2022/03/17
  *   input paramenter: 
  *         data_blk_ptr: inital address of waiting calculation data, 
  *         usDataLen: length of data frame
  *   output parameter:
  *         crc_sum: CRC16-modbus results' inital address
  *   returned value:
  *         checked result - TRUE or FALSE (bool)   
  */
void update_crc(int* crc_sum, int *data_blk_ptr, int data_blk_size)
{
      unsigned int i;
      unsigned short crc = 0xFFFF;
      unsigned short crcl;

      while(data_blk_size--){
            crc ^= *data_blk_ptr++;
            for (i = 0; i < 8; ++i){
                  if (crc & 1)
                        crc = (crc >> 1) ^ 0xA001;
                  else
                        crc = (crc >> 1);
            }
      }
      crcl = crc;
      crc_sum[1] = (unsigned char)(crc>>8);
      crc_sum[0] = (unsigned char)(crcl);
}
int SerialInit(){
    com.setBufferSize(1000000,1000000);
    if(!com.openSyn("COM3", 38400, NOPARITY,8, ONESTOPBIT))
    {
        cout << com.getSerialLastError() << endl;
        getchar();
        return 0;
    }
    return 1;
    
}

int main(){
    string s;
    ofstream outf;
    ifstream inf;
    int totalCount = 0;
    int crcckcount = 0;
    SerialInit();
    // //移除时间戳
    inf.open("./angle.txt");         
    //打开输出文件
    outf.open("./removetimestamp.txt");     
    while (getline(inf, s))     
    {
        if(s.length() >=77){
            outf << s << '\n';
            totalCount++;
        }
        cout << s << endl;
    }
    cout<<"the number of effective frame: "<<totalCount<<endl;
    
    inf.close();
    outf.close();
    //移除时间戳结束
    system("pause");
    cout<<"data processing Running..."<<endl;
    crcckcount = 0;
    inf.open("./removetimestamp.txt");   
    outf.open("./result.txt");  
    string hexS;
    char hexCharqrray[52];
    char* pchar = hexCharqrray;
    totalCount = 0;
    while (getline(inf, hexS))     
    {
        int charcount = 0;
        if(hexS.length() >=FRAME_LEN*3-1){
            // outf << hexS << '\n';
            for(int i = 0; i <78; i++){
                    cwFlag = i%3; 
                    switch(cwFlag){
                        case 0:{
                            // cout<<"hexS["<<i<<"]"<<hexS[i]<<", ";
                            tempdat[0] = byte_2_str(hexS[i]);
                            // cout<<" converted value #0: "<<tempdat[0]<<endl;
                        }break;
                        case 1:{
                            // cout<<"hexS["<<i<<"]"<<hexS[i]<<", ";
                            tempdat[1] = byte_2_str(hexS[i]);
                            // cout<<" converted value #1: "<<tempdat[1]<<" and ";
                            // cout<<(tempdat[0]<<8)<<tempdat[1]<<endl;
                            // hexdat = (tempdat[0]*16) | tempdat[1];
                            
                            // cout<<"converted hex value in decimal: 0X"<<hex<<hexdat<<endl;

                        }break;
                        case 2:{
                            if(charcount < FRAME_LEN){
                                framebuffer[charcount] = tempdat[0]*16+ tempdat[1];
                                charcount++;  
                            }
                            
                        }break;
                        default:break;
                    }

                    // pchar[charcount] = hexS[i];
                    
                    
            }
            cout<<endl;
            totalCount++;
        }
        else{
            cout<<"Error: the length of this line is: "<<hexS.length()<<endl;
        }
        
        cout <<"String result: "<< hexS << endl;
        cout<<"Converted Value: ";
        for(uint16_t i = 0; i < FRAME_LEN; i++){
            cout<<"0X"<<hex<<framebuffer[i]<<", ";
            outf<<"0X"<<hex<<framebuffer[i]<<", ";
            serialbuffer[i] = framebuffer[i];
            
        }
        //check CRC16 modbus
        // system("pause");
        cout<<"CRC check biginning: "<<endl;
        update_crc(crcckrst, framebuffer, FRAME_LEN - 2);
        if((crcckrst[0] == framebuffer[24])&&(crcckrst[1] == framebuffer[25])){
            cout<<"The "<<dec<< totalCount <<"th line CRC check result is PASS."<<endl;
            crcckcount++;
        }
        else{
            cout<<"The "<<dec<< totalCount <<"th line CRC check result is FAIL."<<endl;
            cout<<"crcckrst[0] "<<crcckrst[0] <<"crcckrst[1]"<<crcckrst[1]<<"framebuffer[24]"<<framebuffer[24]<<"framebuffer[25]"<<framebuffer[25]<<endl;
        }
        
        // serial sending data 
        com.writeData(serialbuffer,FRAME_LEN);
        Sleep(25);
        outf <<endl;
        cout<<endl;
    }
    //close serial port
    com.closeComm();
    // close txt files
    inf.close();
    outf.close();

    cout<<"data processing end..."<<endl;
    cout<<"Totally, "<<totalCount<<" frames was converted."<<endl;
    cout<<"Totally, "<<crcckcount<<" frames CRC16 check PASSED"<<endl;
    cout<<"Totally, "<<(totalCount - crcckcount) <<" frames CRC check FAILED."<<endl;

    return 0;
}

SerialInterface.h文件内容

#ifndef __SerialInterface_H_
#define __SerialInterface_H_
#include <Windows.h>
#include <string>
using namespace std;

class SerialInterface
{
private:
    /* data */
    HANDLE hCom;
    string last_error;
public:
    SerialInterface();
    ~SerialInterface();
public:
    //同步方式打开串口,并配置默认信息
    bool openSyn(string serial_name,unsigned int baud_rate,unsigned char parity, unsigned char byte_size, unsigned char stop_bits);
    //同步方式打开串口(需自己配置串口参数)
    bool openSyn(string serial_name);

    //设置推荐的缓冲大小
    bool setBufferSize(DWORD inputBuff,DWORD outBuffer);
    //设置超时
    bool setTimeouts(COMMTIMEOUTS &timeouts);
    //设置串口信息
    bool setDCB(DCB& dcb);

    //刷新缓冲区
    bool purgeBuff(DWORD flags);
    //刷新缓冲区
    bool flushBuff();
    //写数据
    DWORD writeData(char *buffer,int length);
    //读数据
    DWORD readData(char *buffer,int length);
    //写字符串
    DWORD writeStr(string str);
    //关闭串口
    void closeComm();
    //判断串口是否打开
    bool isOpened();
    //得到最后一次失败的错误信息
    string getSerialLastError();
private:
    //设置最后一次的错误信息
    void setSerialLastError(string error_msg);
    //清chu最后一次的错误信息
    void clearSerialLastError();
};

#endif /*__SerialInterface_H_*/

SerialInterface.cpp 文件内容

特别说明的是,可能是因为版本问题,函数:


bool SerialInterface::openSyn(string serial_name, unsigned int baud_rate, unsigned char parity, unsigned char byte_size, unsigned char stop_bits)

中的参数baud_rate有原来的char类型改为unsigned int 类型,用于解决函数中传参数据丢失进而引发G++报warning的问题。

#include "SerialInterface.h"

/*******************************************************************
* 名称: openSyn
* 功能: 同步方式打开串口,并配置默认信息
* 参数:
    serial_name:串口名称
    baud_rate  :波特率,取值如下
        ......
        CBR_9600    9600bps
        CBR_14400   14400bps
        ......
    parity     :校验方式
        EVENPARITY  偶校验
        MARKPARITY  标号校验
        NOPARITY    无校验
        ODDPARITY   奇校验
        SPACEPARITY 空格校验
    byte_size  :数据位大小
        4,5,6,7,8
    stop_bits  :停止位
        ONESTOPBIT      1个停止位
        ONE5STOPBITS    1.5个停止位
        TWOSTOPBITS     2个停止位
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
bool SerialInterface::openSyn(string serial_name, unsigned int baud_rate, unsigned char parity, unsigned char byte_size, unsigned char stop_bits)
{
    if (!openSyn(serial_name))
        return false;
    DCB dcb;

    if (false == GetCommState(hCom, &dcb))//获得当前串口的配置信息
    {
        setSerialLastError("SerialInterface::open() : GetCommState Error");
        return false;
    }

    dcb.DCBlength = sizeof(DCB);
    dcb.BaudRate = baud_rate;
    dcb.Parity = parity;
    dcb.ByteSize = byte_size;
    dcb.StopBits = stop_bits;

    if (false == SetCommState(hCom, &dcb))//用DCB结构重新配置串行端口信息
    {
        setSerialLastError("SerialInterface::open() : SetCommState Error");
        return false;
    }

    //超时处理
    COMMTIMEOUTS timeouts;
    timeouts.ReadIntervalTimeout = MAXDWORD; //读间隔超时
    // 把间隔超时设为最大,把总超时设为0将导致ReadFile立即返回并完成操作 

    timeouts.ReadTotalTimeoutMultiplier = 0; //读时间系数
    timeouts.ReadTotalTimeoutConstant = 0; //读时间常量
    timeouts.WriteTotalTimeoutMultiplier = 50; // 写时间系数
    timeouts.WriteTotalTimeoutConstant = 2000; //写时间常量
    //总的读/写超时时间 = Read(Write)TotalTimeoutMultiplier x 要读/写的字节数 + Read(Write)TotalTimeoutConstant. 
    if (false==SetCommTimeouts(hCom, &timeouts))
    {
        setSerialLastError("SerialInterface::open() : SetCommTimeouts Error");
        return false;
    }



    //清空缓冲区,为读写串口做准备
    if (false == PurgeComm(hCom, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT))
    {
        setSerialLastError("SerialInterface::open() : PurgeComm Error");
        return false;
    }
    return true;
}
/*******************************************************************
* 名称: openSyn
* 功能: 同步方式打开串口(需自己配置串口参数)
* 参数:
    serial_name:串口名称
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
bool SerialInterface::openSyn(string serial_name)
{
    hCom = CreateFileA(
        serial_name.data(),//普通文件名或者设备文件名,这里是串口名
        GENERIC_READ | GENERIC_WRITE,//访问模式,读和写
        0,//共享模式,独占模式
        NULL,//指向安全属性的指针,不使用,传NULL
        OPEN_EXISTING,//如何创建,在串口中必须设置为OPEN_EXISTING。表示不能创建新端口只能打开已有的端口。
        FILE_ATTRIBUTE_NORMAL,//文件属性,使用默认属性FILE_ATTRIBUTE_NORMAL。
        NULL//用于复制文件句柄,通常这个参数设置为NULL,为空表示不使用模板
    );


    if (INVALID_HANDLE_VALUE == hCom)//出错判断
    {
        hCom = NULL;
        setSerialLastError("open():CreateFileA Error!");
        return false;
    }
    return true;
}
/*******************************************************************
* 名称: closeComm
* 功能: 关闭串口
* 参数: 无
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
void SerialInterface::closeComm()
{
    if(NULL==hCom)
        return;
    CloseHandle(hCom);
    hCom=NULL;
}
/*******************************************************************
* 名称: closeComm
* 功能: 判断串口是否打开
* 参数: 无
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
bool SerialInterface::isOpened()
{
    return NULL == hCom ? false : true;
}

DWORD SerialInterface::readData(char *buffer,int length)
{
    DWORD writeSize=0;

    bool ret=false;

    ret=ReadFile(hCom,buffer,length,&writeSize,NULL);

    if(false==ret)
        return 0;

    return writeSize;
}


DWORD SerialInterface::writeData(char *buffer,int length)
{
    DWORD writeSize=0;

    bool ret=false;

    ret=WriteFile(hCom,buffer,length,&writeSize,NULL);

    if(false==ret)
        return 0;

    return writeSize;

}


DWORD SerialInterface::writeStr(string str)
{
    bool ret = false;

    DWORD writeSize = 0;


    ret = WriteFile(hCom, str.data(), str.length(), &writeSize, NULL);

    if (0 == ret)
    {
        last_error = "Error By writeStr(string str)";
        return 0;
    }
        

    last_error = "";
    return writeSize;

}
/*******************************************************************
* 名称: setTimeouts
* 功能: 设置超时
* 参数:
    timeouts:超时配置的COMMTIMEOUTS结构体
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
bool SerialInterface::setTimeouts(COMMTIMEOUTS &timeouts)
{

    if (false == SetCommTimeouts(hCom, &timeouts))
    {
        setSerialLastError("SerialInterface::setTimeouts() : SetCommTimeouts Error");
        return false;
    }
    return true;
}
/*******************************************************************
* 名称: setDCB
* 功能: 设置串口信息
* 参数:
    dcb:串口信息配置的DCB结构体
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
bool SerialInterface::setDCB(DCB& dcb)
{
    if (false == SetCommState(hCom, &dcb))
    {
        setSerialLastError("SerialInterface::setDCB() : SetCommState Error");
        return false;
    }
    return true;
}
/*******************************************************************
* 名称: purgeBuff
* 功能: 刷新缓冲区
* 参数: 
    flags:需要完成的操作,取值如下
        PURGE_RXABORT 终止所有未完成的重叠读取操作并立即返回,即使读取操作尚未完成。
        PURGE_RXCLEAR 清除输入缓冲区(如果设备驱动程序有一个)。
        PURGE_TXABORT 终止所有未完成的重叠写操作并立即返回,即使写操作尚未完成。
        PURGE_TXCLEAR 清除输出缓冲区(如果设备驱动程序有一个)。
* 返回: 正确返回为ture,错误返回为false
* 提示:PurgeComm()函数可以在读写操作的同时,清空缓冲区。当应用程序在读写操作时
调用PurgeComm()函数,不能保证缓冲区内的所有字符都被发送。
*******************************************************************/
bool SerialInterface::purgeBuff(DWORD flags)
{

    if (false == PurgeComm(hCom, flags))
    {
        setSerialLastError("SerialInterface::purgeBuff() : PurgeComm Error");
        return false;
    }
    return true;
}
/*******************************************************************
* 名称:flushBuff
* 功能:刷新缓冲区
* 参数:无
* 返回:正确返回为ture,错误返回为false
* 提示:该函数只受流量控制的支配,不受超时控制的支配,它在所有的写操作完成后才返回。
*******************************************************************/
bool SerialInterface::flushBuff()
{
    if(FlushFileBuffers(hCom))
    {
        setSerialLastError("SerialInterface::flushBuff() : FlushFileBuffers Error");
        return false;
    }
    return true;
}
/*******************************************************************
* 名称: setBufferSize
* 功能: 设置推荐的缓冲大小
* 参数:
    inputBuff:输入缓冲大小
    outBuffer:输出缓冲大小
* 返回: 正确返回为ture,错误返回为false
*******************************************************************/
bool SerialInterface::setBufferSize(DWORD inputBuff,DWORD outBuffer)
{
    if(inputBuff<=0||outBuffer<=0)
        return false;
    
    return SetupComm(hCom,inputBuff,outBuffer);
}
/*******************************************************************
* 名称: getSerialLastError
* 功能: 得到最后一次失败的错误信息
* 参数: 无
* 返回: 数据类型:string,错误信息
*******************************************************************/
string SerialInterface::getSerialLastError()
{
    return last_error;
}

void SerialInterface::setSerialLastError(string error_msg)
{
    last_error = error_msg;
}
void SerialInterface::clearSerialLastError()
{
    last_error = "";
}
SerialInterface::SerialInterface()
{
    hCom=NULL;
}
SerialInterface::~SerialInterface()
{

}

整理于2023年2月23日23:54

标签:false,CRC16,int,C++,Modbus,crc,SerialInterface,串口,return
From: https://www.cnblogs.com/Mech-Snake/p/17149940.html

相关文章

  • C++ primer 5th 第二章 变量和基本类型 阅读笔记
    第二章变量和基本类型第一节基本内置类型C++标准规定了算术类型尺寸的最小值,同时允许编译器赋予这些类型更大的尺寸。比如:类型含义最小尺寸bool布尔类型......
  • C++的内存模型
    C++的内存包含4个大区,它们分别是代码区、全局区、栈区和堆区。以下将对它们的分区进行进一步的阐述。代码区:对于一段代码,首先要经过编译之后生成可执行文件才能执行,在Wi......
  • C++学习(2)STL八股文
    1、STL实现原理及其实现STL提供了六⼤组件,彼此之间可以组合套⽤,这六⼤组件分别是:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器。STL六⼤组件的交互关系:a.容......
  • C++问题集
    const函数名后,加const使类的成员函数,不能修改类内成员。mutable可以突破const限制!在函数后面加const只能在类的成员函数中实现!普通的函数是无法进行这样的操作的!vo......
  • C/C++图书管理系统[2023-02-23]
    C/C++图书管理系统[2023-02-23](辅修)高级语言程序设计课程设计图书管理系统设计并实现一个学校图书馆的图书管理系统。具体要求:1、 图书信息和借阅信息等保存在文本文......
  • C++主函数参数
    学习C++主函数的参数输入,用于从commandline中读取参数,下面以读取视频文件为例进行说明#include<iostream>#include<fstream>#include<string>#include<opencv2/op......
  • C/C++宠物信息管理系统[2023-02-23]
    C/C++宠物信息管理系统[2023-02-23]计算机科学与技术专业课程设计任务书学生姓名专业班级学号题目宠物信息管理系统主要内容开发一个简单的宠物信息管理系统。要......
  • C++基础-2 const auto auto decltype....
                           ......
  • c++线程的使用
    c++11之后,c++语言提供了并发编程的语言支持。c++11增加了线程以及线程相关的类。c++11提供的线程类叫做std::thread,创建线程只需提供线程函数或者函数对象,并且可以指定参......
  • C++入门
    #include<iostream>usingnamespacestd;intmain(){ cout<<"helloworld"<<endl; return0;}一、C++中的头文件(一)climits头文件climits(在老式实现中为limit......