本篇实现双色球预测系统项目
需求
统计一段时间内双色球各数字出现的次数.一期双色球由六个红球和一个蓝球组成,红球数字范围为1-33,蓝球为1-16.
代码总览:
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
#define LINE 7
using namespace std;
bool analyse(const char *filename,int redball[],int blueball[]);
int main(void){
string filename;
int redball[33]={0};
int blueball[16]={0};
cout<<"请输入要分析的文件:";
cin>>filename;
if(analyse(filename.c_str(),redball,blueball)){
for(int i=0;i<33;i++)printf("红球%d出现的次数:%d\n",i+1,redball[i]);
printf("\n");
for(int i=0;i<16;i++)printf("蓝球%d出现的次数:%d\n",i+1,blueball[i]);
}
else{
cout<<"分析失败"<<endl;
}
system("pause");
return 0;
}
bool analyse(const char *filename,int redball[],int blueball[]){
int result[LINE];
bool end=true;
ifstream file;
if(!filename){
cout<<"空路径!!!"<<endl;
return false;
}
else{
file.open(filename);
if(file.fail()){
cout<<"文件打开失败!!!"<<strerror(errno)<<endl;
return false;
}
do{
for(int i=0;i<LINE;i++){
file>>result[i];
if(file.eof()){
end=false;
break;
}
if(file.fail()){
cout<<"文件读取失败!!!"<<strerror(errno)<<endl;
return false;
}
}
for(int i=0;i<LINE-1;i++){
redball[result[i]-1]++;
}
blueball[result[LINE-1]-1]++;
if(!end){
end=true;
break;
}
}while(1);
file.close();
}
return true;
}
需要用到的数据:(往期双色球中奖号码,保存在文件ball.txt中)
03 14 20 24 26 33 10
04 06 08 11 30 33 11
01 14 17 20 22 32 04
06 09 11 15 20 26 10
12 20 24 25 30 33 12
01 14 19 22 29 31 16
07 13 16 23 26 30 01
03 17 19 24 27 31 12
03 04 14 20 23 27 01
04 05 07 09 16 18 06
07 08 12 21 23 27 12
04 05 06 08 13 18 16
13 14 17 19 21 29 01
01 06 11 15 19 31 10
07 10 11 15 24 26 11
04 16 22 25 29 31 08
03 06 09 13 16 19 16
08 09 10 13 15 28 09
04 06 10 11 21 23 02
03 10 13 22 23 28 15
03 07 10 12 18 29 10
03 11 18 25 30 33 14
02 12 16 22 25 32 06
01 06 17 19 27 31 14
06 14 16 17 23 29 07
01 06 12 13 24 32 13
15 17 19 22 25 26 04
02 09 13 23 24 26 16
05 06 09 18 23 31 11
06 07 11 14 27 32 08
主函数里有一个用法要注意,就是string中的.c_str(),c++中提供了一个新的字符串类型,而又兼容c中的字符数组,当string类要转化成c语言中的字符类型时可以使用这个函数,它返回一个const char*类型的指针.
c_str是Borland封装的String类中的一个函数,它返回当前字符串的首字符地址
到了这篇文章,大家对文件的操作应该都很熟悉了,主函数内的代码逻辑也很简单,我们重点讲解函数analyse里的内容.
首先要讲一个需要注意的点,你不能永远默认用户或其他程序员的输入是合法的,你编写的函数或程序要有异常处理部分,比如本应该输入一个整数,用户可能会误输入一个字符,这个时候你的程序要能够判断出这种异常情况并做出处理(重新输入 非法输入警告等等)这就叫防御式编程.
防御式编程是提高软件质量技术的有益辅助手段。防御式编程的主要思想是:子程序应该不因传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据。这种思想是将可能出现的错误造成的影响控制在有限的范围内。
bool analyse(const char *filename,int redball[],int blueball[]){
int result[LINE];
bool end=true;
ifstream file;
if(!filename){
cout<<"空路径!!!"<<endl;
return false;
}
else{
file.open(filename);
if(file.fail()){
cout<<"文件打开失败!!!"<<strerror(errno)<<endl;
return false;
}
......
bool类型是c++中的一个新的类型,它的值只有两种:true和false.函数analyse首先就对路径的合法性做了判断,判断是否是空路径,然后打开文件,用.fail()判断文件是否打开成功.
strerror:
通过标准错误的标号,获得错误的描述字符串 ,将单纯的错误标号转为字符串描述,方便用户查找错误
errno:
errno 是记录系统的最后一次错误代码。代码是一个int型的值,在errno.h中定义。查看错误代码errno是调试程序的一个重要方法
来看看它的具体会输出些什么
......
do{
for(int i=0;i<LINE;i++){
file>>result[i];
if(file.eof()){
end=false;
break;
}
if(file.fail()){
cout<<"文件读取失败!!!"<<strerror(errno)<<endl;
return false;
}
}
for(int i=0;i<LINE-1;i++){
redball[result[i]-1]++;
}
blueball[result[LINE-1]-1]++;
if(!end){
end=true;
break;
}
}while(1);
file.close();
}
return true;
}
.eof()用来判断文件是否读取完毕,未完毕返回0,完毕返回真,redball和blueball数组用来存储对应号码出现的次数,end变量为标志位.在循环中,有时候不能直接跳出来,常用的处理方式是设置一个标志位,配合if语句后在不同的情况下可以执行不同的语句.在这里根据end的值决定是否退出循环,最后用.close()关闭文件.
运行效果: