C++ の日付と時刻
C++ 標準ライブラリは、いわゆる日付型を提供しません。C++ は、日付と時刻の操作のために C 言語から構造と関数を継承します。日付と時刻に関連する関数と構造体を使用するには、C++ プログラムでヘッダー ファイルを参照する必要があります。
時間に関連するタイプには、 Clock_t、time_t、size_t、および tm の 4 つがあります。タイプ Clock_t、size_t、および time_t は、システムの時刻と日付をある種の整数として表すことができます。
構造体タイプ tm は日付と時刻を C 構造体の形式で保存します。tm 構造体の定義は次のとおりです。
構造体 tm {
int tm_sec; // 秒、通常は 0 ~ 59 の範囲ですが、最大 61 秒まで許容されます
int tm_min; // 分、範囲は 0 ~ 59
int tm_hour; // 時間、範囲は 0 ~ 23
int tm_mday; // 日付、範囲は 1 ~ 31
int tm_mon; // 月、範囲は 0 ~ 11
int tm_year; // 1900 年からの年数
int tm_wday; // 日曜日から数えた 0 ~ 6 の範囲の曜日
int tm_yday; // 1 月 1 日から数えた 0 ~ 365 の範囲の通算日
int tm_isdst; // 夏時間
};
以下は、C/C++ の日付と時刻に関連する重要な関数です。これらの関数はすべて C/C++ 標準ライブラリの一部であり、各関数の詳細は C++ 標準ライブラリで確認できます。
シリアルナンバー |
機能と説明 |
1 |
この関数は、システムの現在のカレンダー時刻、1970 年 1 月 1 日からの秒数を返します。システムに時間がない場合は -1 を返します。 |
2 |
char *ctime(const time_t *time); これは、現地時間を表す文字列へのポインタを文字列の形式で返します。 日、月、年、時:分:秒、年\n\0 。 |
3 |
struct tm *localtime(const time_t *time); この関数は現地時間へのポインタを返します。 TM 構造体へのポインタ。 |
4 |
この関数は、プログラム実行の開始 (通常はプログラムの開始) からプロセッサ クロックによって経過した時間を返します。時間が利用できない場合は -1 を返します。 |
5 |
char * asctime ( const struct tm * time ); この関数は、時刻が指す構造体に格納されている情報を含む文字列へのポインタを返します。戻り形式は、日、月、日付、時:分:秒、年\n\0 です。 |
6 |
struct tm *gmtime(const time_t *time); この関数は、グリニッジ標準時 (GMT) とも呼ばれる協定世界時 (UTC) で表現される tm 構造体である時刻へのポインターを返します。 |
7 |
time_t mktime(struct tm *time); この関数は、time が指す構造体に格納されている時刻に相当するカレンダー時刻を返します。 |
8 |
double difftime ( time_t time2, time_t time1 ); この関数は、time1 と time2 の差を秒単位で返します。 |
9 |
この関数を使用すると、日付と時刻を指定した形式にフォーマットできます。 |
現在の日付と時刻
次の例では、現地時間と協定世界時 (UTC) を含む、現在のシステムの日付と時刻を取得します。
例
#include iostream>
#include ctime>
名前空間 std を使用します。
int main()
{
// 現在のシステムに基づく現在の日付/時刻
time_t now = time(0);
// 今すぐ文字列形式に変換します
char* dt = ctime(&now);
cout "ローカルの日付と時刻:" dt endl;
// ここで tm 構造体に変換します
tm *gmtm = gmtime(&now);
dt = asctime(gmtm);
cout "UTC 日付と時刻:" dt endl;
}
上記のコードをコンパイルして実行すると、次の結果が生成されます。
現地日時: 2011 年 1 月 8 日土曜日 20:07:41 UTC 日時: 2011 年 1 月 9 日日曜日 03:07:41
struct tm を使用して時刻をフォーマットする
tm 構造体は、C/C++ で日付と時刻に関連した操作を処理する場合に特に重要です。tm 構造体は日付と時刻を C 構造体として保持します。ほとんどの時間関連関数は tm 構造体を使用します。次の例では、tm 構造体とさまざまな日付と時刻に関連する関数を使用します。
構造体の使用を練習する前に、C 構造体の基本と、矢印 -> 演算子を使用して構造体のメンバーにアクセスする方法を理解する必要があります。
例
#include iostream>
#include ctime>
名前空間 std を使用します。
int main()
{
// 現在のシステムに基づく現在の日付/時刻
time_t now = time(0);
cout "1970 経過秒:" now endl;
tm *ltm = ローカルタイム(&now);
// tm 構造体のさまざまなコンポーネントを出力します
cout "年: "1900 + ltm->tm_year endl;
cout "月: "1 + ltm->tm_monendl;
cout "日: "ltm->tm_mday endl;
cout "時間: "ltm->tm_hour ":";
cout ltm->tm_min ":";
cout ltm->tm_sec endl;
}
上記のコードをコンパイルして実行すると、次の結果が生成されます。
1970年から現在:1503564157年:2017年月:8日:24時間:16:42:37
C++ の基本的な入出力
C++ 標準ライブラリは、豊富な入出力関数セットを提供します。これについては、後続の章で紹介します。この章では、C++ プログラミングにおける最も基本的で一般的な I/O 操作について説明します。
C++ I/O は、バイトのシーケンスであるストリーム上で発生します。バイト ストリームがデバイス (キーボード、ディスク ドライブ、ネットワーク接続など) からメモリに流れる場合、それは入力操作と呼ばれます。バイトのストリームがメモリからデバイス (ディスプレイ画面、プリンター、ディスク ドライブ、ネットワーク接続など) に流れる場合、これは出力操作と呼ばれます。
I/Oライブラリヘッダファイル
次のヘッダー ファイルは C++ プログラミングにおいて重要です。
ヘッドファイル |
機能と説明 |
このファイルは以下を定義します シン、クート、セラー そして 詰まる オブジェクト。それぞれ、標準入力ストリーム、標準出力ストリーム、バッファなしの標準エラー ストリーム、バッファありの標準エラー ストリームに対応します。 |
|
ファイルは、いわゆるパラメータ化されたストリーム マニピュレータ (たとえば、 セット そして 設定精度 )、標準化された I/O の実行に役立つサービスを宣言します。 |
|
このファイルは、ユーザー制御のファイル処理宣言に使用されます。詳細については、ファイルとストリームに関する関連する章で説明します。 |
標準出力ストリーム (cout)
事前定義オブジェクト cout は、iostream クラスのインスタンスです。cout オブジェクトは、標準出力デバイス (通常はディスプレイ) に「接続」します。cout はストリーム挿入演算子と同じです
例
#include iostream>
名前空間 std を使用します。
int main()
{
char str[] = "こんにちは C++";
cout "str の値は次のとおりです: " str endl;
}
上記のコードをコンパイルして実行すると、次の結果が生成されます。
str の値は次のとおりです: Hello C++
C++ コンパイラは、出力される変数のデータ型に基づいて値を表示するための適切なストリーム挿入演算子を選択します。
ストリーム挿入演算子 endl
行末に改行文字を追加するために使用されます。
標準入力ストリーム (cin)
事前定義オブジェクト cin は、iostream クラスのインスタンスです。cin オブジェクトは、標準の入力デバイス (通常はキーボード) に接続されます。cin は、次のようにストリーム抽出演算子 >> と組み合わせて使用されます。
例
#include iostream>
名前空間 std を使用します。
int main()
{
文字名[50];
cout "あなたの名前を入力してください: ";
シン >> 名前;
cout "あなたの名前は: " name endl;
}
当上面的代码被编译和执行时,它会提示用户输入名称。当用户输入一个值,并按回车键,就会看到下列结果:
请输入您的名称: cplusplus 您的名称是: cplusplus
C++ 编译器根据要输入值的数据类型,选择合适的流提取运算符来提取值,并把它存储在给定的变量中。
流提取运算符 >> 在一个语句中可以多次使用,如果要求输入多个数据,可以使用如下语句:
cin >> name >> age;
这相当于下面两个语句:
cin >> name; cin >> age;
标准错误流(cerr)
预定义的对象 cerr 是 iostream 类的一个实例。cerr 对象附属到标准输出设备,通常也是显示屏,但是 cerr 对象是非缓冲的,且每个流插入到 cerr 都会立即输出。
cerr 也是与流插入运算符
实例
#include iostream>
using namespace std;
int main( )
{
char str[] = "Unable to read....";
cerr "Error message : " str endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
Error message : Unable to read....
标准日志流(clog)
预定义的对象 clog 是 iostream 类的一个实例。clog 对象附属到标准输出设备,通常也是显示屏,但是 clog 对象是缓冲的。这意味着每个流插入到 clog 都会先存储在缓冲区,直到缓冲填满或者缓冲区刷新时才会输出。
clog 也是与流插入运算符
实例
#include iostream>
using namespace std;
int main( )
{
char str[] = "Unable to read....";
clog "Error message : " str endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
Error message : Unable to read....
通过这些小实例,我们无法区分 cout、cerr 和 clog 的差异,但在编写和执行大型程序时,它们之间的差异就变得非常明显。所以良好的编程实践告诉我们,使用 cerr 流来显示错误消息,而其他的日志消息则使用 clog 流来输出。
C++ 数据结构
C/C++ 数组允许定义可存储相同类型数据项的变量,但是结构是 C++ 中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。
结构用于表示一条记录,假设您想要跟踪图书馆中书本的动态,您可能需要跟踪每本书的下列属性:
- Title :标题
- Author :作者
- Subject :类目
- Book ID :书的 ID
定义结构
为了定义结构,您必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:
struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;
type_name 是结构体类型的名称,member_type1 member_name1 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在结构定义的末尾,最后一个分号之前,您可以指定一个或多个结构变量,这是可选的。下面是声明一个结构体类型 Books,变量为 book:
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
} book;
访问结构成员
为了访问结构的成员,我们使用成员访问运算符(.)。成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。
下面的实例演示了结构的用法:
实例
#include iostream>
#include cstring>
using namespace std;
// 声明一个结构体类型 Books
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定义结构体类型 Books 的变量 Book1
Books Book2; // 定义结构体类型 Books 的变量 Book2
// Book1 详述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "编程语言");
Book1.book_id = 12345;
// Book2 详述
strcpy( Book2.title, "CSS 教程");
strcpy( Book2.author, "Runoob");
strcpy( Book2.subject, "前端技术");
Book2.book_id = 12346;
// 输出 Book1 信息
cout "第一本书标题 : " Book1.title endl;
cout "第一本书作者 : " Book1.author endl;
cout "第一本书类目 : " Book1.subject endl;
cout "第一本书 ID : " Book1.book_id endl;
// 输出 Book2 信息
cout "第二本书标题 : " Book2.title endl;
cout "第二本书作者 : " Book2.author endl;
cout "第二本书类目 : " Book2.subject endl;
cout "第二本书 ID : " Book2.book_id endl;
return 0;
}
实例中定义了结构体类型 Books 及其两个变量 Book1 和 Book2。当上面的代码被编译和执行时,它会产生下列结果:
第一本书标题 : C++ 教程 第一本书作者 : Runoob 第一本书类目 : 编程语言 第一本书 ID : 12345 第二本书标题 : CSS 教程 第二本书作者 : Runoob 第二本书类目 : 前端技术 第二本书 ID : 12346
结构作为函数参数
您可以把结构作为函数参数,传参方式与其他类型的变量或指针类似。您可以使用上面实例中的方式来访问结构变量:
实例
#include iostream>
#include cstring>
using namespace std;
void printBook( struct Books book );
// 声明一个结构体类型 Books
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定义结构体类型 Books 的变量 Book1
Books Book2; // 定义结构体类型 Books 的变量 Book2
// Book1 详述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "编程语言");
Book1.book_id = 12345;
// Book2 详述
strcpy( Book2.title, "CSS 教程");
strcpy( Book2.author, "Runoob");
strcpy( Book2.subject, "前端技术");
Book2.book_id = 12346;
// 输出 Book1 信息
printBook( Book1 );
// 输出 Book2 信息
printBook( Book2 );
return 0;
}
void printBook( struct Books book )
{
cout "书标题 : " book.title endl;
cout "书作者 : " book.author endl;
cout "书类目 : " book.subject endl;
cout "书 ID : " book.book_id endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
书标题 : C++ 教程 书作者 : Runoob 书类目 : 编程语言 书 ID : 12345 书标题 : CSS 教程 书作者 : Runoob 书类目 : 前端技术 书 ID : 12346
指向结构的指针
您可以定义指向结构的指针,方式与定义指向其他类型变量的指针相似,如下所示:
struct Books *struct_pointer;
现在,您可以在上述定义的指针变量中存储结构变量的地址。为了查找结构变量的地址,请把 & 运算符放在结构名称的前面,如下所示:
struct_pointer = &Book1;
为了使用指向该结构的指针访问结构的成员,您必须使用 -> 运算符,如下所示:
struct_pointer->title;
让我们使用结构指针来重写上面的实例,这将有助于您理解结构指针的概念:
实例
#include iostream>
#include cstring>
using namespace std;
void printBook( struct Books *book );
struct Books
{
char title[50];
char author[50];
char subject[100];
int book_id;
};
int main( )
{
Books Book1; // 定义结构体类型 Books 的变量 Book1
Books Book2; // 定义结构体类型 Books 的变量 Book2
// Book1 详述
strcpy( Book1.title, "C++ 教程");
strcpy( Book1.author, "Runoob");
strcpy( Book1.subject, "编程语言");
Book1.book_id = 12345;
// Book2 详述
strcpy( Book2.title, "CSS 教程");
strcpy( Book2.author, "Runoob");
strcpy( Book2.subject, "前端技术");
Book2.book_id = 12346;
// 通过传 Book1 的地址来输出 Book1 信息
printBook( &Book1 );
// 通过传 Book2 的地址来输出 Book2 信息
printBook( &Book2 );
return 0;
}
// 该函数以结构指针作为参数
void printBook( struct Books *book )
{
cout "书标题 : " book->title endl;
cout "书作者 : " book->author endl;
cout "书类目 : " book->subject endl;
cout "书 ID : " book->book_id endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
書籍名: C++ チュートリアル ブック 著者: Runoob 書籍カテゴリ: プログラミング言語 書籍 ID: 12345 書籍名: CSS チュートリアル ブック 著者: Runoob 書籍カテゴリ: フロントエンド テクノロジ 書籍 ID: 12346
typedef キーワード
ここでは、作成した型を「エイリアス」できる構造体を定義する簡単な方法を示します。例えば:
typedef struct Books { char title[50]; char著者[50]; 文字サブジェクト[100]; int book_id; }本;
struct キーワードを使用せずに、Books を直接使用して、Books 型の変数を定義できるようになりました。以下に例を示します。
書籍 Book1、Book2。
次のように、typedef キーワードを使用して非構造体型を定義できます。
typedef long int *pint32; パイント32 x、y、z;
x、y、z はすべて long int へのポインタです。
ルーキーチュートリアルから移行