文章目录
- 0. 判断一个数是否等于0
- 1. typename和using
- 2. 从txt文本里读取自定义的struct变量
- 3. STL的vector(及string)
- 3.1 输出vector的内容
- 3.2 csv文件读成vector(string处理)
- 3.3 比较复杂的csv
- 3.4 字符串根据某个字符分割(类似python的split)
- 3.4.1 写法1
- 3.4.2 写法2
- 3.4.3 其他
- 3.5 合并vector(把一个vector插入到另一个vector后面)
- 3.6 vector最大值最小值及对应index
- 3.7 vector赋值给另一个vector
- 3.8 vector指针的问题
- 3.9 vector求均值
- 4. 跨平台
- 4.0 C++标准数据类型数据范围
- 4.1 标准数据类型名称
- 4.2 visual studio程序跨平台运行
- 5. 通用功能代码片段
- 5.1 argv接受命令行传递参数
- 5.1.1 visual studio中设置命令行传递的参数
- 5.2 测量某段C++代码执行时间
- 5.3 C++终止程序执行的库函数
- 5.4 C++中bool转int,string转float,string转int
- 5.5 C++的try catch块
- 5.6 C++写文件
- 6. C++风格指南/开发规范
- 6.1 文字版
- 6.2 代码加注释的配图
- 6.3 一些说明
- 其它
-
0. 判断一个数是否等于0
参考:
- 脚本之家:C++ float、double判断是否等于0问题
- 知乎话题:C++里面如何判断等于0?
- stack overflow:Comparing floating point number to zero
1. typename和using
参考:
- using, typename的用法, typedef、using, remove_cv,void_t
- 在C++中,using声明语句=后面的typename起什么作用?
- Using typename的理解
2. 从txt文本里读取自定义的struct变量
Mat4F getMatrix(std::string matFile) {
Mat4F matrix;
std::ifstream in(matFile.c_str());
if (!in) {
std::cerr << "File can't be opened! " << std::endl;
system("PAUSE");
exit(1);
}
in >> matrix.xx >> matrix.xy >> matrix.xz >> matrix.xw >> matrix.yx >> matrix.yy >> matrix.yz >> matrix.yw >> matrix.zx >> matrix.zy >> matrix.zz >>
matrix.zw >> matrix.wx >> matrix.wy >> matrix.wz >> matrix.ww;
std::cout << "current matrix is:" << std::endl;
std::cout << matrix.xx << " " << matrix.xy << " " << matrix.xz << " " << matrix.xw << " " << matrix.yx << " " << matrix.yy << " " << matrix.yz << " "
<< matrix.yw << " " << matrix.zx << " " << matrix.zy << " " << matrix.zz << " " << matrix.zw << " " << matrix.wx << " " << matrix.wy << " "
<< matrix.wz << " " << matrix.ww;
return matrix;
}
参考:
- Reading file into array of struct c++
- c plus plus网站:
- 函数定义:https://cplusplus.com/reference/fstream/ifstream/
- 函数示例:https://cplusplus.com/doc/tutorial/files/
传递结构体作为函数参数
3. STL的vector(及string)
参考:
- CSDN博客:std::vector使用简介
- c中文网:C++ STL vector添加元素(push_back()和emplace_back())详解
3.1 输出vector的内容
如果要嵌套输出一个vector(即vector里的元素还是个vector),可以
for (std::vector<std::vector<int>>::iterator it = pathVector.begin(); it != pathVector.end(); ++it) {
for (vector<int>::iterator it1 = (*it).begin(); it1 != (*it).end(); ++it1) { cout << *it1 << " "; }
std::cout << std::endl;
}
for (const auto& v : extvec)
{
for (auto i : v)
{
cout << i << endl;
}
}
for (int outer = 0; outer < pathVector.size(); outer++) {
std::vector<int> lineVector = pathVector[outer];
for (int inner = 0; inner < lineVector.size(); inner++) { std::cout << lineVector[inner] << " "; }
std::cout << std::endl;
}
参考:
- C++ 中求string和vector容器大小、长度
- stackoverflow:How to print out the contents of a nested vector in c++?
以下代码来自CSDN博客:C++ STL vector的输出,感谢博主!
#define _SCL_SECURE_NO_WARNINGS
#include <vector>
#include <iostream>
#include <algorithm>
#include <windows.h>
using namespace std;
void fun(int i){
cout << i;
}
int main(){
vector<int> vec;
for (int i = 0; i < 10; i++){
vec.push_back(i);
}
for (int i = 0; i < 10; i++){
cout << vec[i];
}
cout << endl;
for (int i = 0; i < 10; i++){
cout << vec.at(i);
}
cout << endl;
cout << vec.back() << endl;
vector<int>::iterator ite = vec.begin();
for (; ite != vec.end(); ite++){
cout << *ite;
}
cout << endl;
for_each(vec.begin(), vec.end(), fun);
cout << endl;
system("pause");
return 0;
}
3.2 csv文件读成vector(string处理)
一行是一个vector,最后返回一个嵌套的vector
std::vector<std::vector<std::string>> readCsvFile(std::string filePath) {
std::vector<std::vector<std::string>> linesVector;
std::ifstream csvData(filePath, std::ios::in);
if (!csvData.is_open()) { throw "error: opening file fail."; }
std::string line;
std::istringstream ss;
std::string element;
std::vector<std::string> lineVector;
while (std::getline(csvData, line)) {
ss.clear();
ss.str(line);
lineVector.clear();
while (getline(ss, element, ',')) { lineVector.emplace_back(element); }
linesVector.emplace_back(lineVector);
}
if (linesVector.size() <= 0) { std::cout << "waring: the csv file is empty." << std::endl; }
return linesVector;
}
std::vector<int> csv2Vector(std::string filePath) {
std::vector<std::vector<int>> linesVector;
std::ifstream csvData(filePath, std::ios::in);
if (!csvData.is_open()) { throw "error: opening file fail."; }
std::string line;
std::istringstream ss;
std::string element;
std::vector<int> lineVector;
lineVector.clear();
while (std::getline(csvData, line)) {
ss.clear();
ss.str(line);
for (int i = 0; i < 4; i++) {
getline(ss, element, ',');
if (i != 0) { lineVector.emplace_back(std::stoi(element)); }
}
}
if (linesVector.size() <= 0) { std::cout << "waring: the csv file is empty." << std::endl; }
return lineVector;
}
参考:
- stackoverflow:Using getline with CSV
3.3 比较复杂的csv
371 328 202,383 343 205,399 364 214,408 369 214,
281 199 178,295 179 185,300 154 196,308 145 212,294 118 224,
212 238 223,206 233 216,200 228 210,196 218 203,
360 372 224,358 378 221,354 371 218,
对于稍微复杂一点的csv,例如上面,逗号分割一组值,其中每个逗号分割的内容又是一组空格分割的值。代码如下:
std::ifstream csvData(filePath, std::ios::in);
if (!csvData.is_open()) { throw "error: opening file fail."; }
std::istringstream singleLine;
std::string line;
std::istringstream singleSeeds;
std::string valueGroup;
std::string oneValue;
struct Vec3UI32 oneSeed;
std::vector<unsigned int> oneSeedVec;
while (std::getline(csvData, line)) {
singleLine.clear();
singleLine.str(line);
linesVector.clear();
while (getline(singleLine, valueGroup, ',')) {
oneSeedVec.clear();
singleSeeds.clear();
singleSeeds.str(valueGroup);
std::cout << valueGroup << std::endl;
while (getline(singleSeeds, oneValue, ' ')) {
std::cout << oneValue << std::endl;
oneSeedVec.emplace_back(std::stoi(oneValue));
}
oneSeed.x = oneSeedVec[0];
oneSeed.y = oneSeedVec[1];
oneSeed.z = oneSeedVec[2];
linesVector.emplace_back(oneSeed);
}
allImgPnts.emplace_back(linesVector);
}
for (const auto& v : allImgPnts) {
std::cout << "One seeds group:";
for (auto i : v) { std::cout << i.x << " " << i.y << " " << i.z << ", "; }
std::cout << std::endl;
}
3.4 字符串根据某个字符分割(类似python的split)
3.4.1 写法1
我目前能看懂,也觉得实现比较简单的
using namespace std;
vector<string> split(string str, char delimiter) {
vector<string> internal;
stringstream ss(str);
string tok;
while(getline(ss, tok, delimiter)) {
internal.push_back(tok);
}
return internal;
}
这种写法是目前搜到比较普遍的一种方法了,类似的还有
- stackoverflow:read input separated by whitespace(s) or newline…?
- GeeksforGeeks:Split a sentence into words in C++
void removeDupWord(string str)
{
istringstream ss(str);
string word;
while (ss >> word)
{
cout << word << "\n";
}
}
3.4.2 写法2
参考:Split String by Space in C++
int main(){
string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
"Sed laoreet sem leo, in posuere orci elementum.";
char space_char = ' ';
vector<string> words{};
stringstream sstream(text);
string word;
while (std::getline(sstream, word, space_char)){
word.erase(std::remove_if(word.begin(), word.end(), ispunct), word.end());
words.push_back(word);
}
for (const auto &str : words) {
cout << str << endl;
}
return EXIT_SUCCESS;
}
这种直接会清除文本中的一些无意义字符,对于格式不那么规范的文档,比较适用
3.4.3 其他
std::vector<std::string> split(std::string str, std::string pattern) {
std::string::size_type pos;
std::vector<std::string> result;
str += pattern;
int size = str.size();
for (int i = 0; i < size; i++) {
pos = str.find(pattern, i);
if (pos < size) {
std::string s = str.substr(i, pos - i);
result.push_back(s);
i = pos + pattern.size() - 1;
}
}
return result;
}
这种就比较生硬,把上面的用现有函数简化一下就是:
int main(){
string text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
"Sed laoreet sem leo, in posuere orci elementum.";
string space_delimiter = " ";
vector<string> words{};
size_t pos = 0;
while ((pos = text.find(space_delimiter)) != string::npos) {
words.push_back(text.substr(0, pos));
text.erase(0, pos + space_delimiter.length());
}
for (const auto &str : words) {
cout << str << endl;
}
return EXIT_SUCCESS;
}
上面代码来自 Split String by Space in C++
vector<string> inputWords;
string input, word;
cin >> input;
stringstream s(input);
while (getline(s, word, ';')) { inputWords.push_back(word); }
vector<string>::iterator it;
for (it = inputWords.begin(); it != inputWords.end(); it++) { cout << *it << endl; }
参考:
- How do I split a string by space into an array in c++?
3.5 合并vector(把一个vector插入到另一个vector后面)
- 有两个vector,vector1和vector2,要把vector2中的所有元素都添加到vector1中
- 类似python里有两个列表,list1和list2,要把list2里的元素都逐个添加到list1中,可以
# python
list1.extend(list2)
# C++
vector1.insert( vector1.end(), vector2.begin(), vector2.end() );
参考:
- C++如何合并若干个vector
- stackoverflow:Concatenating two std::vectors
3.6 vector最大值最小值及对应index
参考:
- c++求vector中的最大值和对应的索引
- Finding the position of the maximum element
3.7 vector赋值给另一个vector
参考:
- C++ 如何将一个vector内容赋值给另一个vector?(注意:auto是内存拷贝,没法改原值;auto&是引用,才能改原值)
3.8 vector指针的问题
转自C++总结1-vector的指针
想要获得vector的数组的指针,可以
&vec[0]
vec.data()
求整个向量的长度,例如:
std::vector<float> demo;
sizeof(float)*vec.size();
用途,想把这个vector的内存空间赋值给另一种object,比如图像的buffer,来进行数据类型的转换
3.9 vector求均值
针对对象是(std::vector<float>
#include <vector>
#include <numeric>
#include <iostream>
float average(std::vector<float> const& v){
if(v.empty()){
return 0;
}
auto const count = static_cast<float>(v.size());
return std::reduce(v.begin(), v.end()) / count;
}
int main(){
std::vector<float> v{8, 4, 2, 7, 5};
auto const a = average(v);
std::cout << "average: " << a << "\n";
}
参考:
- stackoverflow-find average of input to vector c++
4. 跨平台
4.0 C++标准数据类型数据范围
数据类型 | 存储空间/字节数 | 取值范围 |
---|
char | 1字节 | 默认-128 到 127 ,编译时使用/j 则是0 到 255 |
unsigned char | 1字节 | 0 到 255 |
signed char | 1字节 | -128 到 127 |
int | 4 字节 | -2147483648 到 2147483647 |
unsigned int | 4 字节 | 0 到 4294967295 |
signed int | 4字节 | -2147483648 到 2147483647 |
short 别名:short int/signed short int | 2 字节 | -32768 到 32767 |
unsigned short int | 2 字节 | 0 到 65,535 |
float | 4 字节 | 精度型占4个字节(32位)内存空间,+/- 3.4e +/- 38 (~7 个数字) |
double | 8 字节 | 双精度型占8 个字节(64位)内存空间,+/- 1.7e +/- 308 (~15 个数字) |
参考:
- 菜鸟教程:C++ 数据类型
- 上面的部分内容翻译自:Data Type Ranges
- 类似于菜鸟教程的网站还有:
- C++ Data Types
- geeksforgeeks: C++ Data Types
4.1 标准数据类型名称
可以在visual studio中对类似uint8_t
的标识符进行右击,就会跳转到stdint.h
这个头文件中,就会看到类似于下面的代码
#include <vcruntime.h>
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
其中,关于unsigned char
,不太有印象的可以看看
- 百度百科——unsigned char
- 百度百科-char
参考:
- C++规范:Fixed width integer types (since C++11)
- CSDN博客:int8_t、int16_t、int32_t、int64_t、uint8_t、size_t、ssize_t区别
- 知乎文章:C语言尽量使用int8_t int64_t等数据类型
4.2 visual studio程序跨平台运行
常规情况下,visual studio写的程序都是在windows上编译的。
但是感谢如何使用Visual Studio 2017作为Linux C++开发工具
- 我以前以为visual studio可以直接选择linux的编译环境
- 但是其实都是连接远程linux环境进行调试的
- 具体使用需要进行一些配置。
详见:
- 如何使用Visual Studio 2017作为Linux C++开发工具
- Visual C++ for Linux Development with CMake
5. 通用功能代码片段
之前就觉得python添加参数/配置就挺麻烦的,现在看来,C++更麻烦,哈哈哈。
5.1 argv接受命令行传递参数
5.1.1 visual studio中设置命令行传递的参数
根据在VS中向命令行添加参数的方法
右击项目
,选择属性
,找到配置属性
->调试
,在命令参数
中添加要传递的args参数
参考:
- stackoverflow:Use command line arguments argv to create data file with the same name
- 一个C编程教学系列网站:Command line arguments in C++ using argc and argv
5.2 测量某段C++代码执行时间
参考:
- geeksforgeeks:Measure execution time of a function in C++
- stackoverflow:Measuring execution time of a function in C++
- stackoverflow:How to Calculate Execution Time of a Code Snippet in C++
- 8 Ways to Measure Execution Time in C/C++
- 知乎:测量程序运行时间(C++篇)
5.3 C++终止程序执行的库函数
示例:
#include <iostream>
using namespace std;
main() {
bool my_bool;
my_bool = true;
cout << "The int equivalent of my_bool is: " << int(my_bool) << endl;
my_bool = false;
cout << "The int equivalent of my_bool is: " << int(my_bool);
}
输出:
The int equivalent of my_bool is: 1
The int equivalent of my_bool is: 0
参考:
5.4 C++中bool转int,string转float,string转int
std::stof( str )
std::stoi( str )
bool a = false;
int(a)
int a =3;
std::string a = to_string(3);
#include <iostream>
int main()
{ int i = 97;
char ch = static_cast<char>(i);
std::cout << ch << std::endl;
return 0;
}
int main()
{
int N = 97;
cout << char(N);
return 0;
}
int main()
{
int N = 65;
char c = N;
cout << c;
return 0;
}
int main()
{ int N = 1234;
string t = to_string(N);
char const *n_char = t.c_str();
printf("n_char: %s \n",n_char);
return 0;
}
参考:
- Bool to int conversion in C++
- stack overflow:How can I convert a std::string to int?
- Convert int to a char in C++
- C++ Program For int to char Conversion
- https://en.cppreference.com/w/cpp/string/basic_string/stol
另外,类似的还有这个:https://en.cppreference.com/w/cpp/string/byte/atoi
也可以看看:https://cplusplus.com/reference/cstdlib/atoi/
5.5 C++的try catch块
参考:C++ Exceptions
如果不知道try
块中throw
的错误类型,可以在catch
块中使用...
语法,用于处理任意类型的exception
try {
int age = 15;
if (age >= 18) {
cout << "Access granted - you are old enough.";
} else {
throw 505;
}
}
catch (...) {
cout << "Access denied - You must be at least 18 years old.\n";
}
5.6 C++写文件
std::string str(std::string(string.begin(), string.end()));
std::string filename = "/data/data1/hs/ibotTest/LungAirWayDebug/Lung_ATM003_testRadius/testRadius2/001/branConnectRS";
std::ofstream ofs(filename.c_str(), std::ios::trunc);
ofs << str;
ofs.close();
参考:
6. C++风格指南/开发规范
6.1 文字版
一般都用Google的C++开发规范:
- 英语原文链接:Google C++ Style Guide
- 中文在线文档:Google 开源项目风格指南——中文版
- 离线pdf文档:Google 开源项目风格指南(中文版v0.3)
还有一些精简版的C++开发规范:
- Google C++编码规范学习
- 关于代码风格,个人推荐Google C++ Style Guide
6.2 代码加注释的配图
除了这种文字说明,还找到了一个非常贴心的格式说明,直接一张图,代码旁边标注,非常清晰。
感谢一张图总结Google C++编程规范(Google C++ Style Guide)
6.3 一些说明
文件
- 编码是UTF8
- LineEnd是LF,文件批量修改用dos2unix
其中关于第2点的说明,可以参考:
- 知乎问题:为什么大多开源项目的.editorconfig总是设置end_of_line=lf而不是 crlf?
- CSDN文章:关于脚本文件(文本文件)的 Line Endings
其它
C++在线编辑器
有时候想快速测试某段代码,可以直接用在线版本。感谢
推荐10个好用的C++在线编译器,去网吧学习不用配置环境了
我就记住这一个就行
- https://www.cainiaojc.com/tool/cpp/
- https://cppinsights.io/ (不太会用,std::out东西出不来)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)