c++基础实战
1,文件夹相关操作
判断文件夹是否存在,不存在就创建
string pthOut="../demo/resultimg"; int direxists = access(pthOut.c_str(),0); //参数0表示判断是否存在,存在返回0 cout << direxists << endl; //判断文件夹是否存在,存在就返回0 if(direxists!= 0) //不存在就创建 { int mkdirre=mkdir(pthOut.c_str(),S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); cout<<"dir isnt exists"<<mkdirre<<endl; }
1,ubuntu中用access需要用 #include <unistd.h>头文件,
函数原型:int _access(const char *pathname, int mode);需要的参数是char指针,检查模式参数:
00——只检查文件是否存在
02——写权限
04——读权限
06——读写权限
2,ubuntu中用mkdir需要引用头文件#include <sys/stat.h> ,
函数原型:int mkdir(const char *path, mode_t mode); 第二个参数表示新目录的权限,
- User: S_IRUSR (read), S_IWUSR (write), S_IXUSR (execute)
- Group: S_IRGRP (read), S_IWGRP (write), S_IXGRP (execute)
- Others: S_IROTH (read), S_IWOTH (write), S_IXOTH (execute)
- 汇总指令:Read + Write + Execute: S_IRWXU (User), S_IRWXG (Group), S_IRWXO (Others)
3,注意哦,mkdir这个函数的权限设置有问题!什么问题呢,当你想用makedir创建一个0777权限的文件夹的时候,如果你用sudo +执行命令 来执行,你只能得到一个0775的权限的文件夹,如果你用root用户执行(su root的那种),你就只能得到一个0755权限的文件夹,这是为什么?因为ubuntu系统里有个umask,当前用户的umask是0002,而root用户的umask是0022,这个umask有啥用我不清楚,但是0777& ~0022就只能拿到0755,据说这个东西叫屏蔽位,那么怎么解决这个屏蔽位的问题呢?首先你可以设置ubuntu系统内部的umask是0000,这会引起什么后果,估计蛮可怕,不建议使用,第二个方法是想办法绕过c++makedir的这个问题,我先创建文件,再使用chmod修改刚刚创建的文件夹权限,果然完美解决,,真是个小机灵鬼!
#include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <string> #include <iostream> using namespace std; int main(){ string pthOut="./daqing"; int direxists = access(pthOut.c_str(),0); //参数0表示判断是否存在,存在返回0 cout << direxists << endl; //判断文件夹是否存在,存在就返回0 if(direxists!= 0) //不存在就创建 { int mkdirre=mkdir(pthOut.c_str(),0755); int chmrlt=chmod(pthOut.c_str(),S_IRWXU|S_IRWXG|S_IRWXO); cout<<"make dir rlt"<<mkdirre<<endl; cout<<"chmod rlt"<<chmrlt<<endl; } return 0; }
2,文件夹相关的操作
opendir和readdir,用到了结构
https://www.linuxidc.com/Linux/2018-03/151330.htm
https://blog.csdn.net/nuptwanglei/article/details/43051643
https://blog.csdn.net/lin_fs/article/details/7335573
3,sprintf
原型:int sprintf(char *str, const char *format, ...)
第一个参数为char字符数组,足够大就行,比如这样:char a[300];
第二个参数为字符的内容或者说是萝卜的坑,往后的参数是萝卜
实例:
//把整数123 打印成一个字符串保存在s 中。 sprintf(s, "%d", 123); //产生"123" //浮点数的打印格式,默认保存小数点后六位 sprintf(s, "%f", 3.1415926); //产生"3.141593" sprintf(s,"%s%d%c","i love csdn ",123,'N'); sprintf(tmstr,"%4d-%02d-%02d %02d:%02d:%02d",1900+ltm->tm_year,ltm->tm_mon,ltm->tm_mday,ltm->tm_hour,ltm->tm_min,ltm->tm_sec); //格式化字符串,%02d的意思是,整数转化为%d输出,每个占2个字符,如果不足两个字符,就在左侧补上0
%f 传递浮点数,%s传递字符数组,%c传递一个字符
4.memset用于重置一段内存里的内容,据我所知,只能重置为0或者-1
5,键值对map
https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html
6,智能指针:
http://c.biancheng.net/view/1478.html
7,后加加
没想到有一天我会卡在++上,,厉害厉害。
#include <iostream> using namespace std; int main () { int var[3] = {10, 100, 200}; //定义一个c++数组,长度是3,注意这个数组本身就是一个指针 int *ptr= var; //指针赋值 cout << "ptr" << *ptr << endl; //此处再次证实c++数组就是指向数组第一个值的指针 int b=1; int c=b++; //此处理解为,先把b的值赋值给c,然后b自己给自己加上一 cout << "c" << c<<"b"<<b<< endl; //所以此处c是1,b是2 for (int i = 0; i < 3; i++) { cout << "Value of var" << *(ptr++)<<endl; //和b++同理,ptr也是先取值,再进行自增运算 } return 0; }
返回值:
ptr10
c1b2
Value of var10
Value of var100
Value of var200
8,opencv Mat遍历
网上有很多遍历方法,今天只学会了一种,而且非常有参考和纪念意义。
#include <iostream> #include <opencv2/opencv.hpp> #include "stdio.h" int main(){ frame = cv::imread("./xwh11-0718-183032-1.jpg"); uchar* data=frame.ptr<uchar>(); //指向图片的第一个像素的指针,因为图片在内存中都是连续的,所以只需要挨着读就可以啦,小括号里写0也是可以的 for(int r = 0;r<frame.rows*frame.cols;r++){ printf("px is %u ",*(data++)); }
9,层级创建文件夹,
#include <iostream> using namespace std; #ifdef _WIN32 //windows系统 #include <io.h> #include <direct.h> int mkdirs(char *dirpath) { char thisfilename[255]=""; char gang1 = '/'; char gang2 = '\\'; char thisone; int len = strlen(dirpath); for (int i = 0; i<len; i++) { thisone = dirpath[i]; thisfilename[i]=thisone; if (thisone==gang1 || thisone == gang2) { if (_access(thisfilename, 0) == -1) { int mkdirre = _mkdir(thisfilename); if (mkdirre == -1) { printf("log dir error,quit!\n"); return -1; } } else { printf("%s already exists\n", thisfilename); } } } return 0; } #else //ubuntu系统 #include <cstring> //strlen要用的头文件 #include <unistd.h> #include <sys/stat.h> int mkdirs(char *dirpath) { char thisfilename[255] = ""; char gang1 = '/'; char gang2 = '\\'; char thisone; int len = strlen(dirpath); for (int i = 0; i<len; i++) { thisone = dirpath[i]; thisfilename[i] = thisone; if (thisone == gang1 || thisone == gang2) { if (access(thisfilename, 0) == -1) { int mkdirre = mkdir(thisfilename,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); if (mkdirre == -1) { printf("log dir error,quit!\n"); return -1; } else { printf("successfully mkdir %s \n", thisfilename); } } else { printf("%s already exists\n", thisfilename); } } } return 0; } #endif int main() { char hehe[]= "/home/lvnv/temp/t3/"; int result = mkdirs(hehe); printf("mkdirs i got %d \n", result); return 0; }
10,使用ifstream读取文件内容
#include <fstream> #include <string> using namespace std; int main(int argc, char *argv[]) { char cfgpath[] = "D:\\xxx\\yyy\\project\\Config_Camera"; ifstream ifs; ifs.open(cfgpath); cout << "ifs" << endl; string str; if (ifs.is_open()) { cout << "opened" << endl; while (getline(ifs, str)) { cout << "content:" << str.c_str() << endl; } } else { cout << "open faile" << endl; } return 0; }
11,地址拷贝
注意,char数组拷贝到int中,会反过来!int向int中拷贝就不会
memcpy(&sound,rlt,2); #参数:目标地址,把什么东西拷贝到目标地址上去,拷贝几个字节 #头文件#include <string.h>
unsigned int hehe=0; unsigned char rlt[4]={0x00,0x00,0x02,0x16}; //我有一个填充了4个十六进制数的char数组,底层数据应该是这样的: //00000000 00000000 00000010 00010110 memcpy(&hehe,rlt,4); //我把rlt拷贝到hehe上去 printf("%d \n",hehe); //打印出来一个莫名奇妙的数!!!这是为什么呢? //因为拷贝过来的真实数据是这样的: //00010110 00000010 00000000 00000000 囧!! //所以,我如果想拿到十进制的534(二进制是00000010 00010110 )我得手动把char数组写成反的,所以建议大家慎用 //unsigned char rlt[4]={0x16,0x02,0x00,0x00};
12,位运算
还是11的需求,我能拿到两个字节,每个字节都是一个十六进制数,比如0x02,0x16,我要得到十六进制的216所对应的十进制数,534,更快的办法应当是位运算。
这样做
int sound = 0; int sound1=0; sound=0x02; sound1=0x16; int rlt=(sound<<8)+sound1; //解释一下,sound<<8表示把sound的二进制数向左移动八位,空的填写0, // 0x02原本是这样的:00000000 00000000 00000000 00000010 // 移动以后是这样的: 00000000 00000000 00000010 00000000 //移动以后再加上0x16: 00000000 00000000 00000010 00010110也就是534
为什么int可以直接等于一个十六进制数呢?因为他俩底层的二进制是一样的,所以,十进制的2就等于十六进制的0x02