c++编程思想中的数据记录器中的一些问题

今天编写C++编程思想中的输入输出流的简单数据记录器的时候发现源代码中的一些问题。

也许是自己学艺不精,自作聪明,先写给自己看吧。先贴代码

 

首先,我把datalogger.h和datalogger.cpp进行了合并。

想具体了解同名的.h文件和.cpp文件的区别和联系,参看下一个网址,说的很好。

http://blog.csdn.net/bm1408/article/details/606382

 

datalogger.h  头文件

#ifndef DATALOGGER_H
#define DATALOGGER_H
#include<iostream>
#include<iomanip>
#include<iosfwd>
#include<ctime>
#include<string>
#include<sstream>
using namespace std;
using std::ostream;

struct Coord{
	int deg;
	int min;
	int sec;
	Coord(int d=0, int m=0, int s=0)
		: deg(d), min(m), sec(s) {}
	string toString() const;//const
	friend ostream& operator << (ostream&, Coord&);//书中在结构体外声明这个函数,不需要friend声明,因为数据是共有的。。
};

class DataPoint{
public:
	time_t timestamp;
	Coord latitude,longitude;
	double depth,temperature;
public:
	DataPoint(time_t t, Coord& lat, Coord& lon, double d,double tem)
		:timestamp(t), latitude(lat), longitude(lon), depth(d), temperature(tem) {}
	DataPoint(): timestamp(0), depth(0), temperature(0) {}
	friend ostream& operator << (ostream& os,const DataPoint& d);
};

ostream& operator << (ostream& os, Coord& c){
	 os<<c.deg<<'*'<<c.min<<'\''<<c.sec<<'"';//此处输出的同时实现返回os;
	 return os;
}

string Coord::toString() const{
	ostringstream os;//error:不允许使用不完整的类型,解决方法:没有什么大问题,是因为你没有引入对应的头文件:#include <sstream>
	os << this;
	return os.str();
}


ostream& operator << (ostream& os,const DataPoint& d){
	os.setf(ios::fixed, ios::floatfield);//分别是小数点和浮点数计数法。(输出浮点数时候精度固定。)
	char fillc = os.fill('0');//字符0的填充
	time_t t = time(NULL);//获取当前系统的时间。time_t类型的值不适合初始化time_t*类型的实体
    tm tdata;
	localtime_s(&tdata,&t);//引用对象,使用对象的方法调用相应的函数。errno_t localtime_s(struct tm* _tm,const time_t *time );
	//tm* tdata = localtime(&d.timestamp);
	os<<setw(2)<<tdata.tm_mon+1<<'\\'
      <<setw(2)<<tdata.tm_mday<<'\\'
	  <<setw(2)<<tdata.tm_year+1970<<' '
	  <<setw(2)<<tdata.tm_hour<<':'
	  <<setw(2)<<tdata.tm_min<<':'
	  <<setw(2)<<tdata.tm_sec;
	  os.fill(' ');//输完时间之后,填充一个空格。
	  streamsize prec = os.precision(4);//设置流中精度为4;iomanip中定义如下: _CRTIMP _Smanip<streamsize> __cdecl setw(streamsize);
	  os<<" Lat:"<<setw(9)<<d.latitude.toString()
		<<", Long:"<<setw(9)<<d.longitude.toString()
		<<", depth:"<<setw(9)<<d.depth
		<<", temp:"<<setw(9)<<d.temperature;
	  os.fill(fillc);
	  os.precision(prec);
	  return os;
}
#endif

1.在vc6.0中,DataPonint中的变量声明为私有的时候,会出现不能访问的情况。但是在vs2010中就不会出现这种情况。可能与另一个问题有关,现在可能忘记了。。

2. localtime的实现方式有两种

       2.1 tm* tdata = localtime(&d.timestamp),然后按照按照指针访问即可。

       2.2  /*time_t t = time(NULL);   //获取当前系统的时间。time_t类型的值不适合初始化time_t*类型的实体
              tm tdata;
      localtime_s(&tdata,&t);     //引用对象,使用对象的方法调用相应的函数。errno_t  localtime_s(struct tm* _tm,const time_t *time );

             很多时候系统都会指示第一种方式不安全,那就选用第二种方式,。errno_t   localtime_s(struct tm* _tm,const time_t *time ); 是msdn中查到的函数原型。。


             一种是函数返回指针,一种是通过参数实现指针的明确指向。

3. 书中源代码很怪异的一个错误时 os << *this ,error C2679: (二进制“<<”: 没有找到接受“const Coord”类型的右操作数的运算符(或没有可接受的转换)),然后我改成了os << this 就没有了问题。说不出来理由。

4.如果用vc6.0编写程序的时候,会发现expression ptm!=NULL这种问题。问题:空指针作为参数去调用标准库或是什么库的函数,你就会经常看到这种信息。

5.当定义ostringstream的时候出现  error:不允许使用不完整的类型,解决方法:没有什么大问题,是因为你没有引入对应的头文件:#include <sstream>

6.precision 在iomanip中iomanip中定义如下: _CRTIMP _Smanip<streamsize> __cdecl setw(streamsize);  因而有streamsize 类型。。


data_generator产生器代码如下

data_generator.cpp

#include<iostream>
#include<cstdlib>//定义了求模算法,常量 
//NULL, EXIT_FAILURE, EXIT_SUCCESS, RAND_MAX, MB_CUR_MAX 
//函数 atof, atoi, atol, strtod, strtof, strtols, strtol, strtoll, strtoul, strtoull, rand, srand, callc, free, maloc, realloc, abort, atexit, exit, getenv, system, bsearch, qsort, abs, div, labs, ldiv, llabs, tlldiv, mblen, mbtowc, wctomb, mbstowcs, wcstombs
#include<ctime>
#include<string>
#include<fstream>
#include<cassert>
#include"datalogger.h"
using namespace std;

int main(){
	time_t timer;
	srand(time(&timer));//用作产生随机数的种子
	ofstream data("data.txt");
	assert(data);
	assert(data,"data.txt");
	ofstream bindata("bindata.bin");
	assert(bindata);
	//assure(bindata,"bindata.bin");
	for(int i=0;i<100;i++,timer += 55){
		double newdepth = rand()%200;
		double fraction = rand()%100+1;//小数部分
		newdepth += 1.0/fraction;
		double newtemp = 150 +rand()/200;//开氏温度
		fraction = rand()%100 +1;
		newtemp += 1.0/fraction;
		const DataPoint d(timer, Coord(45,35,20), Coord(32,22,16), newdepth, newtemp);
		data<<d<<endl;
		bindata.write(reinterpret_cast<const char*>(&d), sizeof(d));
	}
	return 0;
}
提示

7. warning C4244: “参数”: 从“time_t”转换到“unsigned int”,可能丢失数据   。。这个问题不用管,实际一样运行正确。


本程序很好的实现了文件的写出到外存|硬盘中。而且是结构体到文件中,不会的可以参考这个程序。

8. 翻翻资料了解一下#include<iosfwd>,一般都是出现在头文件中。

9.string 和cstring 的区别,不班门弄斧,给出网址

http://zhidao.baidu.com/question/308090034.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值