Bruce Eckel - Thinking In C++. Volume 2 - Practical Programming

Здесь есть возможность читать онлайн «Bruce Eckel - Thinking In C++. Volume 2 - Practical Programming» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Год выпуска: 2003, ISBN: 2003, Издательство: Prentice Hall, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Thinking In C++. Volume 2: Practical Programming: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Thinking In C++. Volume 2: Practical Programming»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Best selling author Bruce Eckel has joined forces with Chuck Allison to write
, the sequel to the highly received and best selling
. Eckel is the master of teaching professional programmers how to quickly learn cutting edge topics in C++ that are glossed over in other C++ books. In
, the authors cover the finer points of exception handling, defensive programming and string and stream processing that every C++ programmer needs to know. Special attention is given to generic programming where the authors reveal little known techniques for effectively using the Standard Template Library. In addition, Eckel and Allison demonstrate how to apply RTTI, design patterns and concurrent programming techniques to improve the quality of industrial strength C++ applications. This book is targeted at programmers of all levels of experience who want to master C++.

Thinking In C++. Volume 2: Practical Programming — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Thinking In C++. Volume 2: Practical Programming», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

A simple data logger

This example shows an approach you might take to log data to disk and later retrieve it for processing. It is meant to produce a temperature-depth profile of the ocean at various points. To hold the data, a class is used: .

//: C04:DataLogger.h

// Datalogger record layout

#ifndef DATALOG_H

#define DATALOG_H

#include

#include

#include

using std::ostream;

struct Coord {

int deg, min, sec;

Coord(int d = 0, int m = 0, int s = 0)

: deg(d), min(m), sec(s) {}

std::string toString() const;

};

ostream& operator<<(ostream&, const Coord&);

class DataPoint {

std::time_t timestamp; // Time & day

Coord latitude, longitude;

double depth, temperature;

public:

DataPoint(std::time_t ts, const Coord& lat,

const Coord& lon, double dep, double temp)

: timestamp(ts), latitude(lat), longitude(lon),

depth(dep), temperature(temp) {}

DataPoint() : timestamp(0), depth(0), temperature(0) {}

friend ostream& operator<<(ostream&, const DataPoint&);

};

#endif // DATALOG_H ///:~

A DataPointconsists of a time stamp, which is stored as a time_t value as defined in , longitude and latitude coordinates, and values for depth and temperature. We use inserters for easy formatting. Here’s the implementation file: .

//: C04:DataLogger.cpp {O}

// Datapoint implementations

#include "DataLogger.h"

#include

#include

#include

#include

using namespace std;

ostream& operator<<(ostream& os, const Coord& c) {

return os << c.deg << '*' << c.min << '\''

<< c.sec << '"';

}

string Coord::toString() const {

ostringstream os;

os << *this;

return os.str();

}

ostream& operator<<(ostream& os, const DataPoint& d) {

os.setf(ios::fixed, ios::floatfield);

char fillc = os.fill('0'); // Pad on left with '0'

tm* tdata = localtime(&d.timestamp);

os << setw(2) << tdata->tm_mon + 1 << '\\'

<< setw(2) << tdata->tm_mday << '\\'

<< setw(2) << tdata->tm_year+1900 << ' '

<< setw(2) << tdata->tm_hour << ':'

<< setw(2) << tdata->tm_min << ':'

<< setw(2) << tdata->tm_sec;

os.fill(' '); // Pad on left with ' '

streamsize prec = os.precision(4);

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;

} ///:~

The Coord::toString( )function is necessary because the DataPointinserter calls setw( )before it prints the latitude and longitude. If we used the stream inserter for Coordinstead, the width would only apply to the first insertion (that is, to Coord::deg), since width changes are always reset immediately. The call to setf( )causes the floating-point output to be fixed-precision, and precision( )sets the number of decimal places to four. Notice how we restore the fill character and precision to whatever they were before the inserter was called .

To get the values from the time encoding stored in DataPoint::timestamp, we call the function std::localtime( ), which returns a static pointer to a tmobject. The tm structhas the following layout:

struct tm {

int tm_sec; // 0-59 seconds

int tm_min; // 0-59 minutes

int tm_hour; // 0-23 hours

int tm_mday; // Day of month

int tm_mon; // 0-11 months

int tm_year; // Years since 1900

int tm_wday; // Sunday == 0, etc.

int tm_yday; // 0-365 day of year

int tm_isdst; // Daylight savings?

};

Generating test data

Here’s a program that creates a file of test data in binary form (using write( )) and a second file in ASCII form using the DataPointinserter. You can also print it out to the screen, but it’s easier to inspect in file form .

//: C04:Datagen.cpp

// Test data generator

//{L} DataLogger

#include

#include

#include

#include "../require.h"

#include "DataLogger.h"

using namespace std;

int main() {

ofstream data("data.txt");

assure(data, "data.txt");

ofstream bindata("data.bin", ios::binary);

assure(bindata, "data.bin");

time_t timer;

Coord lat(45,20,31);

Coord lon(22,34,18);

// Seed random number generator:

srand(time(&timer));

for(int i = 0; i < 100; i++, timer += 55) {

// Zero to 199 meters:

double newdepth = rand() % 200;

double fraction = rand() % 100 + 1;

newdepth += 1.0 / fraction;

double newtemp = 150 + rand()%200; // Kelvin

fraction = rand() % 100 + 1;

newtemp += 1.0 / fraction;

const DataPoint d(timer, Coord(45,20,31),

Coord(22,34,18), newdepth,

newtemp);

data << d << endl;

bindata.write(reinterpret_cast(&d),

sizeof(d));

}

} ///:~

The file data.txtis created in the ordinary way as an ASCII file, but data.binhas the flag ios::binaryto tell the constructor to set it up as a binary file. To illustrate the formatting used for the text file, here is the first line of data.txt(the line wraps because it’s longer than this page will allow): .

07\28\2003 12:54:40 Lat:45*20'31", Long:22*34'18", depth: 16.0164, temp: 242.0122

The Standard C library function time( )updates the time_tvalue its argument points to with an encoding of the current time, which on most platforms is the number of seconds elapsed since 00:00:00 GMT, January 1 1970 (the dawning of the age of Aquarius?). The current time is also a convenient way to seed the random number generator with the Standard C library function srand( ), as is done here .

After this, the timeris incremented by 55 seconds to give an interesting interval between readings in this simulation .

The latitude and longitude used are fixed values to indicate a set of readings at a single location. Both the depth and the temperature are generated with the Standard C library rand( )function, which returns a pseudorandom number between zero and a platform-dependent constant, RAND_MAX, defined in (usually the value of the platform’s largest unsigned integer). To put this in a desired range, use the remainder operator %and the upper end of the range. These numbers are integral; to add a fractional part, a second call to rand( )is made, and the value is inverted after adding one (to prevent divide-by-zero errors) .

In effect, the data.binfile is being used as a container for the data in the program, even though the container exists on disk and not in RAM. To send the data out to the disk in binary form, write( )is used. The first argument is the starting address of the source block—notice it must be cast to a char*because that’s what write( )expects for narrow streams. The second argument is the number of characters to write, which in this case is the size of the DataPointobject (again, because we’re using narrow streams ). Because no pointers are contained in DataPoint, there is no problem in writing the object to disk. If the object is more sophisticated, you must implement a scheme for serialization , which writes the data referred to by pointers and defines new pointers when read back in later. (We don’t talk about serialization in this volume—most vendor class libraries have some sort of serialization structure built into them.) .

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Thinking In C++. Volume 2: Practical Programming»

Представляем Вашему вниманию похожие книги на «Thinking In C++. Volume 2: Practical Programming» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Thinking In C++. Volume 2: Practical Programming»

Обсуждение, отзывы о книге «Thinking In C++. Volume 2: Practical Programming» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x