Mrli
别装作很努力,
因为结局不会陪你演戏。
Contacts:
QQ博客园

程序设计周cpp学习笔记

2019/09/15 C++ 程序设计
Word count: 2,735 | Reading time: 13min

文件名传参

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using namespace std;
#define FILENAME "data.csv"
void readfile(string file){
ifstream inFile;
inFile.open(file.c_str(), ios::out); // 打开模式可省略
string lineStr;
while (getline(inFile, lineStr) )
// 打印整行字符串
cout << lineStr << '-'<< endl;
}

int main(){
readfile(FILENAME);
return 0;
}

输入Q退出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void studentMenu(){
string UID;
string PWD;
int confirmed = false;
//判断是否认证成功
do{
cout <<"请输入普通账号ID:" <<endl;
cin >> UID;
cout <<"请输入密码:" <<endl;
cin >> PWD;
confirmed = confirmStatus(UID,PWD);
if( !confirmed ) cout << "账号或密码错误,请尝试.账号ID输入'Q'退出";
}while( !confirmed && UID != "Q");
if(confirmed) {
cout << "成功认证";
//进入学生界面
}
}

!!! 标准库文件是在.h还是.cpp中include?

现有两个文件Test.h 和Test.cpp#include <iostream>Test.h中包含 和在Test.cpp中包含有什么区别?

  • 1、在cpp文件中包含.h文件,要么你要用到这个头文件中的函数或者类,要么就是实现这个头文件;
  • 2、.h —就是为了放一堆声明所产生的东西。
    如果是定义放在.h中。 如果.h被重复包含多次,那么则会被报重定义。所以在.h 中都要—如果函数就要是inline ,如果是变量就要 selectany (windows)才不会被报错。
  • 3、#include尽量写到cpp文件里。两个文件在.h文件里相互include,就会产生编译错误,而两个文件在.c文件互相include,就不会有该问题,因此在.h文件include就要避免互相包含的问题,而.cpp文件就不需要考虑
  • 4、1)在 .h 里面 include 的好处是:如果很多.c,.cpp文件,都包含一批头文件,如果复制很容易遗漏,如果输入,很容易出错

如果全部在一个.h, include 那么每个.c,.cpp文件只需要一个#include 语句这样不仅输入量减少,而且代码也美观多了代码也主次分明了毕竟,.c.cpp, 里面要实现的函数,才是主要代码

2)主要缺陷,
可能会包含完全不需要的头文件,
增加编译工作量

  • 5、如果你在a.h头文件中include了“stdio.h”,“iostream”,……一大堆
    那么你的a.cpp源文件只要include你的a.h,就相当于include了“stdio.h”,“iostream”,……一大堆
    但是当其他文件include你的a.h的同时也就包含了“stdio.h”,“iostream”,……一大堆这个要看你个人需要,如果你需要让其他文件也include一大堆,那么写在a.h中就可以,其他文件包含a.cpp简单整洁无脑如果只有a.cpp需要include一大堆,那么还是建议在a.cpp中include一大堆
  • 6、如果a.c包含了头文件a.h,a.h包含了头文件b.h,b.c也包含了b.h,那么当b.h发生改变时,a.c和b.c都会重新编译也就是所有包含了b.h的都会重新编译,无论是直接包含,还是间接包含
  • 7、2点原则:
    • 第一个原则:如果可以不包含头文件,那就不要包含了,这时候前置声明可以解决问题。如果使用的仅仅是一个类的指针,没有使用这个类的具体对象(非指针),也没有访问到类的具体成员,那么前置声明就可以了。因为指针这一数据类型的大小是特定的,编译器可以获知(C++编译器自上而下编译源文件的时候,对每一个数据的定义,总是需要知道定义的数据的类型的大小) 第二个原则:尽量在CPP文件中包含头文件,而非在头文件中。假设类A的一个成员是是一个指向类B的指针,在类A的头文件中使用了类 B的前置声明并编译成功,那么在A的实现中我们需要访问B的具体成员,因此需要包含头文件,那么我们应该在类A的实现部分(CPP文件)包含类B的头文件而非声明部分(H文件)

摘自:https://www.cnblogs.com/fengzhengfly/p/8884581.html


C++ 构造函数的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
using namespace std;
class CUser{
public:
string UID;
int status;
void login();
CUser():UID("0"),status(0){}
CUser(string id,int sts):UID(id),status(sts){}
};
int main(){
CUser user("hello",12);
cout << user.UID << user.status;
getchar();
return 0;
}

string转int

1
2
3
4
5
6
7
8
9
10
11
atoi(rstatus.c_str())  
//atoi("04"); ===> 4 可以忽略0
---
使用stringstream:
string s = "17";
stringstream ss;
ss<<s;
int i;
ss>>i;
cout<<i<<endl; // 17
//stringstream可以吞下任何类型,根据实际需要吐出不同的类型

int转string

1
2
3
4
5
6
int n = 0;
std::stringstream ss;
std::string str;
ss<<n;
ss>>str;
//或者cout << ss.str();
1
itoa(num, str, 10);

string转int

1
2
std::string str = "123";
int n = atoi(str.c_str());

int 转string

1
2
3
4
5
6
7
8
9
10
这是C++11新增的,使用非常方便,简单查了下:C++11标准增加了全局函数std::to_string,
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val)

一.string转char *

  • data()
  • c_str()
  • copy();

1、string转char*。

1
2
3
4
5
6
1 string str = "hello";
2 const char* p = str.data();//加const 或者用char * p=(char*)str.data();的形式
/*
同时有一点需要说明,这里在devc++中编译需要添加const,否则会报错invalid conversion from const char* to char *,这里可以再前面加上const或者在等号后面给强制转化成char*的类型。
  下面解释下该问题,const char*是不能直接赋值到char*的,这样编译都不能通过,理由:假如可以的话,那么通过char*就可以修改const char指向的内容了,这是不允许的。所以char*要另外开辟新的空间,即上面的形式。
  */

2.c_str()方法,如:

1
2
1 string str=“world”;
2 const char *p = str.c_str();//同上,要加const或者等号右边用char*

3.copy()方法,如:

1
2
3
4
1 string str="hmmm";
2 char p[50];
3 str.copy(p, 5, 0);//这里5代表复制几个字符,0代表复制的位置,
4 *(p+5)=‘\0’;//注意手动加结束符!!!

二、char * 转string。

1
2
3
1 string s;
2 char *p = "hello";//直接赋值
3 s = p;

这里有一点要说明,当声明了string类型变量s后,用printf("%s",s);是会出错的,因为“%s”要求后面的对象的首地址。但是string不是这样的一个类型。所以肯定出错。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A{
public:
void co();
void bo();
};

void A::co(){
cout << "hello";
A::bo();
}

void A::bo(){
cout << "world";
}
#include <cstdio>
int main(){
A a;
a.co();
getchar();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main(){
ifstream inFile("data1.csv", ios::in);

if (inFile.fail()){
cout << "Cannot open file" << endl;
return -1;
}
vector<string> line;
string lineStr;
while (getline(inFile, lineStr) ){
line.push_back(lineStr);
}
for(vector<string>::iterator i=line.begin();i!=line.end();i++){
// cout << strArray.at(i)<<endl;
cout << (*i) << endl;
}

getchar();
return 0;
}
1
2
3
4
cout << "请输入书的数量:" << endl;
do{
cin >> tmp.TotalNumber;
}while( atoi( tmp.TotalNumber.c_str()) == 0 ) ; //非数字情况

操作二维Vector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
string lineStr;
vector<vector<string>> strArray;
while (getline(inFile, lineStr) ){
stringstream ss(lineStr);
string str;
vector<string> lineArray;
while (getline(ss, str, ',')) lineArray.push_back(str);
strArray.push_back(lineArray);
for(vector<vector<string>>::iterator i=strArray.begin();i!=strArray.end();i++){
for(vector<string>::iterator j=(*i).begin();j!=(*i).end();j++){
cout << "*j " ;
}
cout << endl;
}
}

改好的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
int main(){
ifstream inFile("data1.csv", ios::in);
vector<vector<string>> lineVec;
if (inFile.fail()){
cout << "Cannot open file" << endl;
return -1;
}

string lineStr;
vector<vector<string>> vecArray;
vector<string> newvec;

while (getline(inFile, lineStr) ){
stringstream ss(lineStr);
string str;
vector<string> lineVec;
while (getline(ss, str, ',')) lineVec.push_back(str);
vecArray.push_back(lineVec);

for(vector<vector<string>>::iterator i=vecArray.begin();i!=vecArray.end();i++){
vector<string>::iterator j=(*i).begin();
if( *j != "100009/1" )
{newvec.push_back(lineStr);
break;
}
}
}

for (std::vector<string>::iterator i = newvec.begin(); i != newvec.end(); ++i)
cout << *i << endl;

system("pause");
return 0;
}

二维Vector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int main(int argc, char const *argv[]){
vector<vector<string>> row;
vector<string> col1;
vector<string> col2;

col1.push_back("Q");
col1.push_back("W");

col2.push_back("A");
col2.push_back("S");

row.push_back(col1);
row.push_back(col2);
cout << row.at(0).at(1);
getchar();
return 0;
}

查看vector中是否含指定的string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main(int argc, char const *argv[])
{
std::vector<string> v;
v.push_back("hello");
v.push_back("1ord");
v.push_back("asd");
if (std::find(v.begin(), v.end(), "he") != v.end())
{
cout << "yes";
}
getchar();
return 0;
}

循环时删除某个元素,不影响循环==>每个元素仍能被遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(){
vector<string> v;
v.push_back("1");
v.push_back("2");
v.push_back("3");
v.push_back("4");
for (int i = 0; i < v.size(); ++i){
if (v.at(i) == "2") v.erase(v.begin()+i);
}
for (int i = 0; i < v.size(); ++i)
cout << v.at(i) << endl;
system("pause");
return 0;
}

跳过索引值,只输出id

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int main(int argc, char const *argv[]){
ifstream inFile;
inFile.open("data1.csv");

string lineStr;
vector<vector<string> > row;
vector<string> newvec;

while (getline(inFile, lineStr) ){
stringstream ss(lineStr);
string str;
vector<string> col;
while (getline(ss, str, ',')) col.push_back(str);
row.push_back(col);
}
for (int i = 1; i < row.size(); ++i)
cout << row.at(i).at(0) << endl;

system("pause");
return 0;
}

避免错误输入

1
while(getchar()!='\n') ;

分割时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
void CData(string &timestr){
stringstream ss(timestr);
int year;
int mon;
int day;
string str;
getline(ss, str, '/');
year = atoi(str.c_str());
getline(ss, str, '/');
mon = atoi(str.c_str());
getline(ss, str, '/');
day = atoi(str.c_str());
cout << year << "," << mon << "," << day << endl;
}

int main(int argc, char const *argv[])
{
// string a ="2017/04/02";
// CData(a);
stringstream ss;
ss << 1 << "/" << 2 << "/" << 3;
cout << ss.str();
getchar();
return 0;
}
1
2
stringstream ss;
ss << 1 << "/" << 2 << "/" << 3;

vector最大值

1
int maxn =  *max_element(v.begin(),v.end());

找到最大ID

1
2
3
4
5
6
7
8
9
10
11
12
vector<string> idcol;
string lineStr;
while (getline(infile, lineStr) ){ //获取行
stringstream ss(lineStr);
string bookid; //记录列数据,必须写在这个循环里
getline(ss, bookid, ',');
idcol.push_back(bookid);
}
int addid = vecMAX(idcol)+1;
stringstream inttostring;
inttostring << addid;
tmp.BookID = inttostring.str();

二维VEC排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(){
std::vector<std::vector<int> > s;
vector<int> v1;
vector<int> v2;
v1.push_back(5);
v1.push_back(13);
s.push_back(v1);
v2.push_back(7);
v2.push_back(4);
s.push_back(v2);
sort(s.begin(), s.end());
for (int i = 0; i < s.size(); ++i){
for (int j = 0; j < v1.size(); ++j)
cout << s.at(i).at(j);
cout << endl;
}
system("pause");
return 0;
}
1
2
3
out.open(USERTMPFILE) 可以打开宏定义
ios::in + ios::out 从开头加
ios::app 从结尾加

获得值最大的键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool cmp(const pair<string, int>& lhs, const pair<string, int>& rhs) {  
return lhs.second > rhs.second;
}

int main(int argc, char const *argv[]){
map<string,int> a ;
a.insert(pair<string, int>("ssd", 3));
a["hello"]=3;
a["world"]=9;
a["cl"]=6;
std::vector< pair<string, int> > v(a.begin(), a.end());
sort(v.begin(), v.end(),cmp);
cout << "max" << v.at(0).first << endl;
getchar();
return 0;
}

Author: Mrli

Link: https://nymrli.top/2019/03/07/程序设计周cpp学习笔记/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
搭建Gitlab服务器
NextPost >
ACM-DFS、BFS
CATALOG
  1. 1. 文件名传参
  2. 2. 输入Q退出
    1. 2.1. !!! 标准库文件是在.h还是.cpp中include?
    2. 2.2. C++ 构造函数的使用
    3. 2.3. string转int
    4. 2.4. int转string
    5. 2.5. int 转string
    6. 2.6. 一.string转char *
      1. 2.6.1. 1、string转char*。
      2. 2.6.2. 2.c_str()方法,如:
      3. 2.6.3. 3.copy()方法,如:
    7. 2.7. 二、char * 转string。
  3. 3. 操作二维Vector
    1. 3.1. 查看vector中是否含指定的string
    2. 3.2. 跳过索引值,只输出id
  4. 4. 避免错误输入
    1. 4.1. 分割时间
    2. 4.2. 找到最大ID
    3. 4.3. 二维VEC排序
    4. 4.4. 获得值最大的键