修练者
建立打开/保存文件对话框
#include<windows.h>
#include<string>
std::string GetFile(char *format)
{
OPENFILENAME ofn;
TCHAR szOpenFileNames[80*MAX_PATH];
TCHAR szPath[MAX_PATH];
TCHAR szFileName[80*MAX_PATH];
TCHAR* p;
int nLen = 0;
ZeroMemory( &ofn, sizeof(ofn) );
ofn.Flags = OFN_EXPLORER;
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = szOpenFileNames;
ofn.nMaxFile = sizeof(szOpenFileNames);
ofn.lpstrFile[0] = '\0';
ofn.lpstrFilter = TEXT(format);
if( GetOpenFileName( &ofn ) )
{
//把第一个文件名前的复制到szPath,即:
//如果只选了一个文件,就复制到最后一个'/'
lstrcpyn(szPath, szOpenFileNames, ofn.nFileOffset );
//当只选了一个文件时,下面这个NULL字符是必需的.
szPath[ ofn.nFileOffset ] = '\0';
nLen = lstrlen(szPath);
if( szPath[nLen-1] != '\\' ) //如果选了多个文件,则必须加上'//'
{
lstrcat(szPath, TEXT("\\"));
}
p = szOpenFileNames + ofn.nFileOffset; //把指针移到第一个文件
ZeroMemory(szFileName, sizeof(szFileName));
while( *p )
{
lstrcat(szFileName, szPath); //给文件名加上路径
lstrcat(szFileName, p); //加上文件名
break;
}
}
return szFileName;
}
std::string SaveFile(char *format)
{
OPENFILENAME ofn;
TCHAR szOpenFileNames[80*MAX_PATH];
TCHAR szPath[MAX_PATH];
TCHAR szFileName[80*MAX_PATH];
TCHAR* p;
int nLen = 0;
ZeroMemory( &ofn, sizeof(ofn) );
ofn.Flags = OFN_EXPLORER;
ofn.lStructSize = sizeof(ofn);
ofn.lpstrFile = szOpenFileNames;
ofn.nMaxFile = sizeof(szOpenFileNames);
ofn.lpstrFile[0] = '\0';
ofn.lpstrFilter = TEXT(format);
if( GetSaveFileName( &ofn ) )
{
return szOpenFileNames;
}
return (std::string)"\0";
}
文件**
#include<bits/stdc++.h>
#include<wp/file.h>
using namespace std;
int main(int argc,char *argv[])
{
string s,filename;
while(1)
{
cout<<">>>";
getline(cin,s);
if(s=="quit")
{
break;
}
else if(s=="open")
{
filename=GetFile("所有文件(*.*)\0*.*\0");
}
else if(s=="write")
{
if(filename!="")
{
ofstream fout(filename.c_str(),ios::app);
if(!fout.is_open())
{
cout<<"No open\n";
continue;
}
string wr;
while(getline(cin,wr))
{
fout<<wr<<endl;
}
cin.clear();
fout.close();
}
}
else if(s=="close")
{
filename="";
}
else if(s=="clear write")
{
if(filename!="")
{
ofstream fout(filename.c_str());
if(!fout.is_open())
{
cout<<"No open\n";
continue;
}
string wr;
while(getline(cin,wr))
{
fout<<wr<<endl;
}
cin.clear();
fout.close();
}
}
else if(s=="new")
{
string ne;
ne=SaveFile("所有文件(*.*)\0*.*\0");
ofstream fout(ne.c_str());
fout.close();
}
else if(s=="read")
{
if(filename!="")
{
ifstream fin(filename.c_str());
if(!fin.is_open())
{
cout<<"No open\n";
continue;
}
char c;
while(fin.get(c))
{
cout<<c;
}
fin.close();
}
}
else if(s=="save")
{
string savename=SaveFile("所有文件(*.*)\0*.*");
ofstream fout(savename.c_str());
ifstream fin (filename.c_str());
char c;
while(fin.get(c))
{
fout.put(c);
}
fout.close();
fin .close();
}
}
return 0;
}
wp/file.h为第一个代码
席清源在2021-12-25 15:35:27追加了内容
GetFile()和SaveFile()的参数格式:
"提示\0格式\0下一个提示\0下一个格式\0……\0"
例如,可以选择 *.* *.txt *.doc/*.docx
"所有文件\0*.*\0文本文件\0*.txt\0Word文档\0*.doc;*.docx"
席清源在2021-12-26 17:49:21追加了内容
@酷町侠 @酷町扫地僧 @酷町猫 @酷町喵~o( =∩ω∩= )o~ @酷丁
可以入围精品贴吗?
席清源在2021-12-31 18:54:54追加了内容
第一节 - 函数参数个数可变
有两种方法,分别是可变参数模板和va_list
先来看可变参数模板:
它用到了模板
不会赶紧学
先来看一个函数show_list0()
template<typename T>
void show_list0(T val)
{
cout<<val<<endl;
}
但是它只能显示一项,可变参数模板的主要内容是:
1.处理
2.递归
我们可以写出一个show_list1()
template<typename... Args>
void show_list1(Args... args)
{
show_list1(args...);
}
但如果调用show_list1(12,"abc",123.0);
会无限递归
递归的正确使用方法是这样的(注意,参数每次减少一项,当变成0项是需要另一个函数)
void show_list2(){}
template<typename T,typename... Args>
void show_list2(T value,Args... args)
{
cout<<value<<",";
show_list2(args...);
}
#include<bits/stdc++.h>
using namespace std;
void show_list2(){}
template<typename Arg,typename... Args>
void show_list2(Arg v,Args... val)
{
cout<<v<<",";
show_list2(val...);
}
int main(int argc,char *argv[])
{
show_list2(15,"abc",38.0);
return 0;
}
当调用show_list2(12,"abc",123.0);
12,abc,123.0,
我们会发现后面多了一个逗号,修正方法是这样的:
void show_list3(){}
template<typename T>
void show_list3(T value)
{
cout<<value<<endl;
}
template<typename T,typename... Args>
void show_list3(T value,Args... args)
{
cout<<value<<",";
show_list3(args...);
}
这样就可以了
#include<bits/stdc++.h>
using namespace std;
void show_list3(){}
template<typename Arg>
void show_list3(Arg v)
{
cout<<v<<endl;
}
template<typename Arg,typename... Args>
void show_list3(Arg v,Args... val)
{
cout<<v<<",";
show_list3(val...);
}
int main(int argc,char *argv[])
{
show_list3("34","It's a taijiquan","vvv");
show_list3(12,123);
return 0;
}
关于用引用来高效传递,下次再说
va_list也下次再说
席清源在2022-01-01 09:32:53追加了内容
va_list是这么用的
先声明一个va_list类型的对象
再调用va_start(va_list,第一个参数名)
获取下一个参数用va_arg(va_list,typename)
好了,废话少说,上代码
#include<bits/stdc++.h>
using namespace std;
int sum(int nCount,int a,...)
{
int sumn=0;
va_list v;
va_start(v,a);
while(nCount--)
{
sumn+=a;
a=va_arg(v,int);
}
return sumn;
}
int main()
{
cout<<sum(5,1,2,3,4,5)<<endl; //15
cout<<sum(3,1,2,3) <<endl; //6
return 0;
}
试试吧,这也是C的函数参数个数可变
请根据需要选择两种方式
席清源在2022-01-02 15:43:54追加了内容
席清源在2022-01-03 17:46:03追加了内容
又做了一个头文件,保存为console.h
#ifndef CONSOLE_H_
#define CONSOLE_H_
void gotoxy(int x, int y)
{
COORD pos = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
void HideCursor()
{
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible=FALSE;
SetConsoleCursorInfo(hOut,&cci);
}
void cls()
{
gotoxy(0,0);
}
#endif
转载自https://blog.csdn.net/wangshanglu/article/details/105317267
席清源在2022-01-03 19:18:07追加了内容
又做了一个头文件,保存为longnum.h
#ifndef LONGNUM_H_
#define LONGNUM_H_
class LongNum
{
string shu;
string jia(string a, string b){
string ans;
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
a.push_back('0'); b.push_back('0');
if(a.size() < b.size()) swap(a, b);
while(b.size() < a.size()) b.push_back('0');
int c[1000]={0}, k = a.size();
for(int i = 0; i < a.size(); i++)
{
int s = c[i] + a[i]-'0' + b[i] - '0';
c[i] = s%10;
c[i+1] += s/10;
}
while(c[k]==0 && k>=0) k--;
while(k >= 0)
ans.push_back(c[k--]+'0');
return ans;
}
string jian(string a, string b){
string ans;
bool flag = false;
if(a.size() < b.size() || (a.size()==b.size() && a < b)){
swap(a, b);
flag = true;
}
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
a.push_back('0'); b.push_back('0');
if(a.size() < b.size()) swap(a, b);
while(b.size() < a.size()) b.push_back('0');
int c[1000]={0}, k = a.size();
for(int i = 0; i < a.size(); i++){
if(a[i] < b[i]) a[i]+=10, a[i+1]--;
c[i] = a[i] - b[i];
}
while(c[k]==0 && k>=0) k--;
if(flag) ans.push_back('-');
while(k >= 0)
ans.push_back(c[k--]+'0');
return ans;
}
string cheng(string a, string b){
string ans;
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
int c[1000]={0}, k = a.size()+b.size()+1;
for(int i = 0; i < a.size(); i++){
for(int j = 0; j < b.size(); j++){
c[i+j] += (a[i]-'0')*(b[j]-'0');
c[i+j+1] += c[i+j]/10;
c[i+j] %= 10;
}
}
while(c[k]==0 && k>=0) k--;
while(k >= 0){
ans.push_back(c[k--]+'0');
}
return ans;
}
string chu(string a, long long b){
int z[256] = {0}, d = 0;
for(int i = 0; i < a.size(); i++)
{
d = 10*d + a[i] - '0';
z[i] = d / b;
d %= b;
}
string ans;
int len = 0;
while(z[len] == 0 && len < a.size()-1)
len++;
for(int i = len; i < a.size(); i++){
ans.push_back(z[i]+'0');
}
return ans;
}
string toString(long long n){
ostringstream sout;
sout<<n;
return sout.str();
}
public:
LongNum(string s="0"){shu=s;}
LongNum(int n){shu=toString(n);}
LongNum(long long n){shu=toString(n);}
LongNum(float) = delete;
LongNum(double) = delete;
LongNum(const LongNum&) = default;
operator string(){return shu;}
LongNum&operator=(string s){shu=s;return *this;}
LongNum&operator=(int n){shu=toString(n);return *this;}
LongNum&operator=(long long n){shu=toString(n);return *this;}
LongNum&operator=(float) = delete;
LongNum&operator=(double) = delete;
LongNum operator+(const LongNum&ln) const {return jia(shu,ln.shu);}
LongNum operator-(const LongNum&ln) const {return jian(shu,ln.shu);}
LongNum operator*(const LongNum&ln) const {return cheng(shu,ln.shu);}
LongNum operator/(const long long&ll) const {return chu(shu,ll);}
LongNum operator+=(const LongNum&ln) {shu=jia(shu,ln.shu);return *this;}
LongNum operator-=(const LongNum&ln) {shu=jian(shu,ln.shu);return *this;}
LongNum operator*=(const LongNum&ln) {shu=cheng(shu,ln.shu);return *this;}
LongNum operator/=(const long long&ll) {shu=chu(shu,ll);return *this;}
};
//转载自https://wenda.codingtang.com/questions/15449/ @ 阿巴
#endif
高精度封装类
席清源在2022-01-06 20:19:46追加了内容
地图生存v1.0.2
游戏介绍:
可以移动
游戏代码:
#include<bits/stdc++.h>
#include<windows.h>
#include<wp/console.h>
using namespace std;
char _map[20][20];
class Player
{
private:
int x,y;
public:
Player(int x_,int y_){x=x_;y=y_;}
void draw()
{
_map[y][x]=' ';
if(KEY_DOWN('A')) x--;
if(KEY_DOWN('W')) y--;
if(KEY_DOWN('D')) x++;
if(KEY_DOWN('S')) y++;
_map[y][x]='x';
}
};
int main(int argc,char *argv[])
{
memset(_map,' ',sizeof(_map));
Player player(0,0);
while(1)
{
player.draw();
cls();
SetColor(0x1f);
for(int i=0;i<20;i++)
{
for(int j=0;j<20;j++)
{
cout<<_map[i][j];
}
cout<<endl;
}
SetColor(0x07);
Sleep(50);
}
return 0;
}
console.h贴一下(使用时把"wp/"删掉)
#ifndef CONSOLE_H_
#define CONSOLE_H_
#include<windows.h>
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
void gotoxy(int x, int y)
{
COORD pos = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
void HideCursor()
{
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cci;
GetConsoleCursorInfo(hOut,&cci);
cci.bVisible=FALSE;
SetConsoleCursorInfo(hOut,&cci);
}
void cls()
{
gotoxy(0,0);
}
void COLOR_PRINT(const char* s, int color)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
printf(s);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | 7);
}
void SetColor(int color)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
}
#endif