日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

UNIX环境高级编程-第六章-系统数据文件和信息

發(fā)布時(shí)間:2023/12/16 windows 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UNIX环境高级编程-第六章-系统数据文件和信息 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.引言

UNIX系統(tǒng)的正常運(yùn)作需要適用大量與系統(tǒng)有關(guān)的數(shù)據(jù)文件,例如,口令文件/etc/passwd和組文件/etc/group就是經(jīng)常被多個(gè)程序頻繁適用的兩個(gè)文件。用戶每次登錄UNIX系統(tǒng),以及每次執(zhí)行l(wèi)s -l命令時(shí)都要使用口令文件。
由于歷史原因,這些數(shù)據(jù)文件都是ASCLL文本文件,并且使用標(biāo)準(zhǔn)IO庫讀這些文件。但是,對于較大的系統(tǒng),順序掃描口令文件很花費(fèi)時(shí)間,我們需要能夠以非ASCII文本格式存放這些文件,但仍向使用其他文件格式的應(yīng)用程序提供接口,對于這些數(shù)據(jù)文件的可移植接口是本章的主題。本章也包括了系統(tǒng)標(biāo)識函數(shù),時(shí)間和日期函數(shù)。

2.口令文件

UNIX系統(tǒng)口令文件(POSIX.1則將其稱為用戶數(shù)據(jù)庫)包含了圖6-1中所示的各字段,這些字段包含了在<pwd.h>中定義的passwd結(jié)構(gòu)中。

由于歷史原因,口令文件是/etc/passwd,而且是一個(gè)ASCII文件。每一行包含圖6-1中所示的各字段,字段之間用冒號分隔。例如,在Linux中,該文件中可能有下列4行:

root:x:0:0:root:/root:/bin/bash squid:x:23:23::/var:spool/squid:/dev/null nobody:x:65534:65534:Nobody:/home:/bin/sh sar:x:205:105:Stephen Rago:/home/sar:/bin/bash

這些登錄項(xiàng),請注意下列各點(diǎn):

(1)通常有一個(gè)用戶名為root的登錄項(xiàng),其用戶ID是0(超級用戶)
(2)加密口令字段包含了一個(gè)占位符。較早期的UNIX系統(tǒng)版本中,該字段存放加密口令字。將加密口令字存放在一個(gè)人人刻度的文件中是一個(gè)安全性漏洞,所以現(xiàn)在將加密口令字存放在另一個(gè)文件中。在下一節(jié)討論口令字時(shí),我們再詳細(xì)解釋
(3)口令文件項(xiàng)中的某些字段可能是空。如果加密口令字段為空,這通常就意味著該用戶沒有口令。squid登錄項(xiàng)有一空白字段:注釋字段,空白注釋字段不產(chǎn)生任何影響。
(4)shell字段包含了一個(gè)可執(zhí)行程序名,它被用作該用戶的登錄shell。若該字段為空,則取系統(tǒng)默認(rèn)值,通常是/bin/sh。注意,squid登錄項(xiàng)的該字段為/dev/null。顯然,這是一個(gè)設(shè)備,不是可執(zhí)行文件,將啟用于此處的目的是,阻止任何人以用戶squid的名義登錄到該系統(tǒng)。
(5)為了阻止一個(gè)特定用戶登陸系統(tǒng),除使用/dev/null外,還有若干種替代方法。常見的一種方法是,將/bin/false用作登錄shell。它簡單地以不成功狀態(tài)終止,該shell將此種終止?fàn)顟B(tài)判斷為假。另一種常見方法是,用/bin/true禁止一個(gè)賬戶。它所做的一切是以成功狀態(tài)終止。某些系統(tǒng)提供nologin命令,它打印可定制的出錯(cuò)信息,然后以非0狀態(tài)終止。
(6)使用nobody用戶名的一個(gè)目的是,是任何人都可以登錄至系統(tǒng),但其用戶ID(65534)和組ID(65534)不提供任何特權(quán)。該用戶ID和組ID只能訪問人人皆可讀,寫的文件。(假定用戶ID65534和組ID65534并不擁有任何文件)
(7)提供finger命令的某些UNIX系統(tǒng)支持注釋字段種的附加信息。其中各部分之間用逗號分隔:用戶姓名,辦公室地點(diǎn),辦公室電話號碼以及家庭電話號碼等。另外,如果注釋字段中的用戶姓名是一個(gè)&,則它被替換為登錄名。例如,可以有下列記錄:
sar:x :205:105:Steve Rago, SF 5-121,
555-1111,555-2222:/home/sar:/bin/sh 使用finger命令就可以打印Steve Rago的有關(guān)信息

某些系統(tǒng)提供了vipw命令,允許管理員使用該命令編輯口令文件。vipw命令串行化地更改口令文件,并且確保它所作的更改與其他相關(guān)文件保持一致。系統(tǒng)也常常經(jīng)由圖形用戶界面提供類似的功能。
POSIX.1定義了兩個(gè)獲取口令文件項(xiàng)的函數(shù)。在給出用戶登錄名或數(shù)值用戶ID后,這兩個(gè)函數(shù)就能查看相關(guān)項(xiàng)。

#include<pwd.h> struct passwd *getpwuid(uid_t uid); struct passwd *getpwnam(const char *name);

getpwuid函數(shù)由ls程序使用,它將i節(jié)點(diǎn)種的數(shù)字用戶ID映射為用戶登錄名。在鍵入登錄名時(shí),getpwnam函數(shù)由login程序使用。
這兩個(gè)函數(shù)都返回一個(gè)指向passwd結(jié)構(gòu)的指針,該結(jié)構(gòu)已由這兩個(gè)函數(shù)在執(zhí)行時(shí)填入信息。passwd結(jié)構(gòu)通常是函數(shù)內(nèi)部的靜態(tài)變量,只要調(diào)用任一相關(guān)函數(shù),其內(nèi)容就會(huì)被重寫。
如果要查看的只是登錄名或用戶ID,那么這兩個(gè)函數(shù)能滿足要求,但是也有些程序要查看整個(gè)口令文件。下列3個(gè)函數(shù)可用于此種目的。

#include <pwd.h> struct passwd *getpwent(void); void setpwent(void); void endpwent(void);

調(diào)用getpwent時(shí),它返回口令文件中的下一個(gè)記錄項(xiàng)。如同上面所述的兩個(gè)POSIX.1函數(shù)一樣,它返回一個(gè)由它填寫好的passwd結(jié)構(gòu)的指針。每次調(diào)用此函數(shù)時(shí)都重寫該結(jié)構(gòu)。
函數(shù)setpwent反繞它所使用的文件,endpwent則關(guān)閉這些文件。在使用getpwent查看完口令文件后,一定要調(diào)用endpwent關(guān)閉這些文件。getpwent知道什么時(shí)間應(yīng)當(dāng)打開它所使用的文件(第一次被調(diào)用時(shí)),但是它并不知道何時(shí)關(guān)閉這些文件。
實(shí)例6-2:給出了getpwnam函數(shù)的一個(gè)實(shí)現(xiàn)。

#include <pswd.h> #include <stddef.h> #include <string.h>struct passwd *getpwnam(const char *name) {struct passwd *ptr;setpwent();while((ptr=getpwent())!=NULL)if(strcmp(name,ptr->pw_name)==0)break;endpwent();return (ptr); }

在函數(shù)開始處調(diào)用setpwent是自我保護(hù)性的措施,以便確保如果調(diào)用者再此之前已經(jīng)調(diào)用getpwent打開了有關(guān)文件的情況下,反繞有關(guān)文件使它們定位到文件開始處。getpwnam和getpwuid完成后不應(yīng)使有關(guān)文件仍處于打開狀態(tài),所以使用endpwent關(guān)閉它們。

3.陰影口令

加密口令是經(jīng)單向加密算法處理過的用戶口令副本。因?yàn)榇怂惴ㄊ菃蜗虻?#xff0c;所以不能從加密口令猜測到原來的口令。
對于一個(gè)加密口令,找不到一種算法可以將其反變換到明文口令。但是可以對口令進(jìn)行猜測,將猜測的口令經(jīng)單向算法變換成加密形式,然后將其與用戶的加密口令比較。如果用戶口令是隨機(jī)選擇的,那么這種方法并不是很有用。但是用戶往往以非隨機(jī)方式選擇口令。一個(gè)經(jīng)常重復(fù)的實(shí)驗(yàn)是先得到一份口令文件,然后試探猜測口令。
為了使企圖這樣做的人難以獲得原始資料,現(xiàn)在,某些系統(tǒng)將加密口令存放在另一個(gè)通常稱為陰影口令的文件中。該文件至少包含用戶名和加密口令。與該口令相關(guān)的其他信息也可存放在該文件中(圖 6-3)。

只有用戶登錄名和加密口令這兩個(gè)字段是必須的。其他的字段控制口令更改的頻率,陰影口令文件不應(yīng)是一般用戶可以讀取的。僅有少數(shù)幾個(gè)程序需要訪問加密口令,如login和passwd,這些程序常常是設(shè)置用戶ID為root的程序。有了陰影口令后,普通口令文件/etc/passwd可由各用戶自由讀取。
與訪問口令文件的一組函數(shù)相類似,有另一組函數(shù)而可用于訪問陰影口令文件。

#include<shadow.h> struct spwd *getspnam(cosnt char *name); struct spwd *getspent(void); void setspent(void); void endspent(void);

4.組文件

UNIX組文件包含了圖6-4中所示的字段。這些字段包含在<grp.h>中所定義的group結(jié)構(gòu)中。

字段gr_mem是一個(gè)指針數(shù)組,其中每個(gè)指針指向一個(gè)屬于該組的用戶名。該數(shù)組以null指針結(jié)尾。可以用下列兩個(gè)由POSIX.1定義的函數(shù)來產(chǎn)看組名或數(shù)值組ID。

#include <grp.h> struct group *getgrgid(gid_t gid); struct group *getgrnam(const char *name);

如同對口令文件進(jìn)行操作的函數(shù)一樣,這兩個(gè)函數(shù)通常也返回指向一個(gè)靜態(tài)變量的指針,在每次調(diào)用時(shí)都重寫該靜態(tài)變量。
如果需要搜索整個(gè)組文件,則需使用另外幾個(gè)函數(shù)。下列3個(gè)函數(shù)類似于針對口令文件的3個(gè)函數(shù)。

#include <grp.h> struct group *getgrent(void); void setgrent(void); void endgrent(void);

setgrent函數(shù)打開組文件并反繞它。getgrent函數(shù)從組文件讀取下一個(gè)記錄,如若該文件尚未打開,則先打開它。endgrent函數(shù)關(guān)閉組我呢見。

5.附屬組ID

在UNIX系統(tǒng)中,對組的使用已經(jīng)作了些修改。在v7中,每個(gè)用戶任何時(shí)候都只屬于一個(gè)組。當(dāng)用戶登陸時(shí),系統(tǒng)就按口令文件記錄項(xiàng)中的數(shù)值組ID,賦給他實(shí)際組ID。可以在任何時(shí)候執(zhí)行newgrp以更改組ID。如果newgrp命令執(zhí)行成功,則實(shí)際組ID就更改為新的組ID,它將被用于后續(xù)的文件訪問權(quán)限檢查。執(zhí)行不帶任何參數(shù)的newgrp,則可返回到原來的組。
這種組成員形式一致維持到1983年左右。此時(shí),4.2BSD引入了附屬組ID的概念。我們不僅可以屬于口令文件記錄項(xiàng)中組ID所對應(yīng)的組,也可屬于多至16個(gè)另外的組。文件訪問權(quán)限檢查相應(yīng)被修改為:不僅將進(jìn)程的有效組ID與文件的組ID相比較,而且也將所有附屬組ID與文件組ID進(jìn)行比較。
使用附屬組ID的優(yōu)點(diǎn)是不必再顯示地經(jīng)常更改組。一個(gè)用戶會(huì)參加多個(gè)項(xiàng)目,因此也就要同時(shí)屬于多個(gè)組,此類情況是常有的。
為了獲取和設(shè)置附屬組ID,提供了下列3個(gè)函數(shù)。

#include <unistd.h> #include <grp.h> #include <unistd.h> int setgroups(int ngroups,const gid_t grouplist[]); int initgroups(const char *username,gid_t basegid); int getgroup(int gidsetsize,gid_t grouplist[])

getgroups將進(jìn)程所屬用戶的各附屬組ID填寫到數(shù)組grouplist中,填寫入該數(shù)組的附屬組ID數(shù)最多為gidsetsize個(gè)。實(shí)際填寫到數(shù)組中的附屬組ID數(shù)由函數(shù)返回。
作為一種特殊情況,如若gidsetsize為0,則函數(shù)只返回附屬組ID數(shù),而對數(shù)組grouplist則不做修改。
setgroups可有超級用戶調(diào)用以便為調(diào)用進(jìn)程設(shè)置附屬組ID表。grouplist是組ID數(shù)組,而ngroups說明了數(shù)組中的元素?cái)?shù)。ngroups的值不能大于NGROUPS_MAX。
通常,只有initgroups函數(shù)調(diào)用setgroups,initgroups讀整個(gè)組文件(用前面說明的函數(shù)getgrent,setgrent和endgrent),然后對username確定其組的成員關(guān)系。然后它調(diào)用setgroups,以便為該用戶初始化附屬組ID表。因?yàn)閕nitgroups要調(diào)用setgroups,所以只有超級用戶才能能調(diào)用initgroups。除了在組文件中找到username是成員的所有組,initgroups也在附屬組ID表中包括了basegid。basegid是username在口令文件中的組ID。

6.其他數(shù)據(jù)文件

至此討論了兩個(gè)系統(tǒng)數(shù)據(jù)文件-口令文件和組文件。
在磁場操作中,UNIX系統(tǒng)還是用很多其他文件。例如BSD網(wǎng)絡(luò)軟件有一個(gè)記錄各網(wǎng)絡(luò)服務(wù)器所提供服務(wù)的數(shù)據(jù)文件(/etc/services),有一個(gè)記錄協(xié)議信息的數(shù)據(jù)文件(/etc/protocols),還有一個(gè)則是記錄網(wǎng)絡(luò)信息的數(shù)據(jù)文件(/etc/networks)。幸運(yùn)的是,對于這些數(shù)據(jù)文件的接口都與上述對口令文件和組文件的相似。
一般情況下,對于每個(gè)數(shù)據(jù)文件至少有3個(gè)函數(shù)。

(1)get函數(shù):讀下一個(gè)記錄,如果需要,還會(huì)打開該文件。此種函數(shù)通常返回指向一個(gè)結(jié)構(gòu)的指針。當(dāng)已到達(dá)文件尾端時(shí)返回空指針。大多數(shù)get函數(shù)返回指向一個(gè)靜態(tài)存儲(chǔ)類結(jié)構(gòu)的指針,如果要保存其內(nèi)容,則需要復(fù)制它。
(2)set函數(shù):打開相應(yīng)數(shù)據(jù)文件(如果尚未打開),然后反繞該文件。如果希望在相應(yīng)文件起始處開始處理,則調(diào)用此函數(shù)。
(3)end函數(shù):關(guān)閉相應(yīng)數(shù)據(jù)文件。如前所述,在結(jié)束了對相應(yīng)數(shù)據(jù)文件的讀,寫操作后,總應(yīng)調(diào)用此函數(shù)以關(guān)閉所有相關(guān)文件。

另外,如果數(shù)據(jù)文件支持某種形式的鍵搜索,則也提供搜索具有指定鍵的記錄的例程。例如,對于口令文件,提供了兩個(gè)按鍵進(jìn)行搜索的程序:getpwnam和getpwuid用于指定用戶的記錄。
圖6-6列出了一些這樣的例程。對于圖中列出的所有數(shù)據(jù)文件都有g(shù)et,set和end函數(shù)。

7.登錄賬戶記錄

大多數(shù)UNIX系統(tǒng)都提供了下列兩個(gè)數(shù)據(jù)文件:utmp文件記錄當(dāng)前登錄到系統(tǒng)的各個(gè)用戶;wtmp文件跟蹤各個(gè)登錄和注銷事件。在v7中,每次寫入這兩個(gè)文件中的是包含下列結(jié)構(gòu)的一個(gè)二進(jìn)制記錄;

struct utmp {char ut_line[8];char ut_name[8];long ut_time; }

登陸時(shí),login程序填寫此類結(jié)構(gòu),然后將其寫入到utmp文件中,同時(shí)也將其添寫到wtmp文件中。注銷時(shí),init進(jìn)程將utmp文件中相應(yīng)的記錄擦除,并將一個(gè)新紀(jì)錄添寫到wtmp文件中。在wtmp文件的注銷記錄中,ut_name字段清除為0.在系統(tǒng)再啟動(dòng)時(shí),以及更改系統(tǒng)事件和日期的前后,都在wtmp文件中追加寫特殊的記錄項(xiàng)。

8.系統(tǒng)標(biāo)識

POSIX.1定義了uname函數(shù),它返回與主機(jī)和操作系統(tǒng)有關(guān)的信息。

#include <sys/utsname.h> int uname(struct utsname *name);

通過該函數(shù)的參數(shù)向其傳遞一個(gè)utsname結(jié)構(gòu)的地址,然后該函數(shù)添寫此結(jié)構(gòu)。POSIX.1只定義了該結(jié)構(gòu)中最少需提供的字段,而每個(gè)數(shù)組的長度則由實(shí)現(xiàn)確定。某些實(shí)現(xiàn)在該結(jié)構(gòu)中提供了另外一些字段。

struct utsname {char sysname[];char nodename[];char release[];char version[];char machine[]; }

每個(gè)字符串都以null字節(jié)結(jié)尾。本書討論的4中平臺支持的最大名字長度列于圖6-7中。utsname結(jié)構(gòu)中的信息通常可用uname命令打印。

BSD派生的系統(tǒng)提供gethostname函數(shù),它只返回主機(jī)名,該名字通常就是TCP/IP網(wǎng)絡(luò)上主機(jī)的名字。

#include <unistd.h> int gethostname(char *name,int namelen);

namelen參數(shù)指定name緩沖區(qū)長度,如若提供足夠的空間,則通過name返回的字符串以null字節(jié)結(jié)尾。如若沒有提供足夠的空間,則沒有說明通過name返回的字符串是否以null結(jié)尾。
現(xiàn)在,getihostname函數(shù)已在POSIX.1中定義,它指定最大主機(jī)名長度是HOST_NAME_MAX。
hostname命令可用來獲取和設(shè)置主機(jī)名。主機(jī)名通常在系統(tǒng)自舉時(shí)設(shè)置,它由/etc/rc或init取自一個(gè)啟動(dòng)文件。

9.時(shí)間和日期例程

由UNIX內(nèi)核提供的基本時(shí)間服務(wù)是計(jì)算自協(xié)調(diào)世界時(shí)公元1970年1月1日00:00:00這一特定時(shí)間以來經(jīng)過的秒數(shù)。1.10節(jié)中曾提及這種秒數(shù)以數(shù)據(jù)類型time_t表示的。我們稱它們?yōu)槿諝v時(shí)間。日歷時(shí)間包括時(shí)間和日期。UNIX在這方面與其他操作系統(tǒng)的區(qū)別是:

(1)以協(xié)調(diào)統(tǒng)一時(shí)間而非本地時(shí)間計(jì)時(shí);
(2)可自動(dòng)進(jìn)行轉(zhuǎn)換,如變換到夏令時(shí)
(3)將時(shí)間和日期作為一個(gè)量值保存

time函數(shù)返回當(dāng)前時(shí)間和日期

#include <time.h> time_t time(time_t *calptr)

時(shí)間值作為函數(shù)值返回。如果參數(shù)非空,則時(shí)間值也存放在由calptr指向的單元內(nèi)。
POSIX的實(shí)時(shí)擴(kuò)展增加了對多個(gè)系統(tǒng)時(shí)鐘的支持。在Single UNIX Specification V4中,控制這些時(shí)鐘的接口從可選組被移到基本組。時(shí)鐘通過clockid_t類型進(jìn)行標(biāo)識。圖6-8給出了標(biāo)準(zhǔn)值。

clock_gettime函數(shù)用于獲取指定時(shí)鐘的時(shí)間,返回的時(shí)間在timespec結(jié)構(gòu)中,它把時(shí)間表示為秒和納秒。

#include <sys/time.h> int clock_gettime(clockid_t clock_id,struct timespec *tsp);

當(dāng)前時(shí)鐘ID設(shè)置為CLOCK_REATIME時(shí),clock_gettime函數(shù)提供了與time函數(shù)類似的功能,不過在系統(tǒng)支持高精度時(shí)間值的情況下,clock_gettime可能比time函數(shù)得到更高精度的時(shí)間值。

#include<sys/time.h> int clock_getres(clockid clock_id,struct timespec *tsp);

clock_getres函數(shù)把參數(shù)tsp指向的timespec結(jié)構(gòu)初始化為與clock_id參數(shù)對應(yīng)的時(shí)鐘精度。例如如果精度為一毫秒,則tv_sec字段就是0,tv_nsec字段就是1000000。
要對特定的時(shí)鐘設(shè)置時(shí)間,可以調(diào)用clock_settime函數(shù)

#include <sys/time.h> int clock_settime(clockid_t clock_id,const struct timespec *tsp);

我們需要適當(dāng)?shù)奶貦?quán)來更改時(shí)鐘值,但是有些時(shí)鐘是不餓能修改的。
圖6-9說明了各種時(shí)間函數(shù)之間的關(guān)系。

兩個(gè)函數(shù)localtime和gmtime將日歷時(shí)間轉(zhuǎn)換成分解的時(shí)間,并將這些存放在一個(gè)tm結(jié)構(gòu)中。

struct tm{int tm_sec;int tm_min;int tm_hour;int tm_mday;int tm_mon;int tm_year;int tm_wday;int tm_yday;int tm_isdst; }

秒可以超過59的理由是可以表示潤秒。注意,除了月日字段,其他字段的值都以0開始。如果夏令時(shí)生效,則夏令時(shí)標(biāo)志值為正;如果為非夏令時(shí)時(shí)間,則該標(biāo)志值為0;如果此信息不可用,則其值為負(fù)。

#include <time.h> struct tm *gmtime(const time_t * calptr); struct tm *localtime(const time_t *calptr);

localtime和gmtime之間的區(qū)別是:localtime將日歷時(shí)間轉(zhuǎn)換成本地時(shí)間(考慮到本地時(shí)區(qū)和夏令時(shí)標(biāo)志),而gmtime則將日歷時(shí)間轉(zhuǎn)換成協(xié)調(diào)統(tǒng)一時(shí)間的年,月,日,時(shí),分,秒,周日分解結(jié)構(gòu)。
函數(shù)mktime以本地時(shí)間的年,月,日等作為參數(shù),將其變換成time_t值。

#include <time.h> time _t mktime(struct tm *tmptr);

函數(shù)strftime是一個(gè)類似于printf的時(shí)間值函數(shù),它非常復(fù)雜,可以通過可用的多個(gè)參數(shù)來定制產(chǎn)生的字符串。

#include <time.h> size_t strftime(char *restrict buf,size_t maxsize,const char *restrict format.const struct tm*restrict tmptr); size_t strftime_l(char *restrict buf,size_t maxsize,const char *restrict format,cosnt struct tm *restrict tmptr,locale_t locale);

strftime_l允許調(diào)用者將區(qū)域指定為參數(shù),除此之外,strftime和strftime_l函數(shù)是相同的。strftime使用通過TZ環(huán)境變量指定的區(qū)域。
tmptr參數(shù)是要格式化的時(shí)間值,由一個(gè)指向分解時(shí)間值tm結(jié)構(gòu)的指針說明。格式化結(jié)果存放在一個(gè)長度為maxsize個(gè)字符的buf數(shù)組中,如果buf長度足以存放格式化結(jié)果及一個(gè)null終止符,則該函數(shù)返回在buf中存放的字符數(shù);否則趕回0.
format參數(shù)控制時(shí)間值的格式。如同printf函數(shù)一樣,轉(zhuǎn)換說明的形式是百分號之后跟一個(gè)特定字符。format中的其他字符按原樣輸出。兩個(gè)連續(xù)的百分號在輸出中產(chǎn)生一個(gè)百分號。與pritnf函數(shù)的不同之處是,每個(gè)轉(zhuǎn)換說明產(chǎn)生一個(gè)不同定長輸出字符串,在format字符串中沒有字段寬度修飾符。圖6-10列出了轉(zhuǎn)換說明:

圖6-10大多數(shù)格式說明的意義很明顯。需要略作解釋的是%U,%V,%W。%U是相應(yīng)日期在該年中所屬周數(shù),包含該年中第一個(gè)星期日的周是第一周。%W也是相應(yīng)日期在該年所屬的周數(shù),不同的是第一個(gè)星期一的周是第一周。%V說明符則與上述兩者有較大區(qū)別。如果包含了1月1日的那一周包含了新一年的4天或更多,那么該周是一年中的第一周;否則該周被認(rèn)為是上一年的最后一周。在這兩種情況下,周一被視作每周的第一天。
實(shí)例6-11:
演示了如何使用本章中討論的多個(gè)時(shí)間函數(shù)。特別演示了如何使用strftime打印包含當(dāng)前日期和時(shí)間的字符串

#include <stdio.h> #include <stdlib.h> #include <time.h>int main(void) {time_t t;struct tm *tmp;char buf1[16];char buf2[64];time(&t);tmp=localtime(&t);if (strftime(buf1,16,"time and date:%r,%a %b %d,%Y",tmp)==0)printf("buffer length 16 is too small\n");elseprintf("%s\n",buf1);if(strftime(buf2,64,"time and date: %r, %a %b %d,%Y",tmp)==0)printf("buffer length of 64 is too small\n");elseprintf("%s\n",buf2);exit(0); }

strptime函數(shù)是strftime的反過來的版本,把字符串時(shí)間轉(zhuǎn)換成分解時(shí)間。

#incldue <time.h> char *strptime(const char *restrict buf,const char *restrict format,struct tm *restrict tmptr);

format參數(shù)給出了buf參數(shù)指向緩沖區(qū)的字符串的格式。雖然與strftime函數(shù)的說明稍有不同,但是格式說明是類似的。strptime函數(shù)轉(zhuǎn)換成說明符列在圖6-12中

我們曾在前面提及,圖6-9中以虛線表示的3個(gè)函數(shù)收到環(huán)境變量TZ的影響。這3個(gè)函數(shù)是localtime,mktime和strftime。如果定義了TZ,則這些函數(shù)將使用其值代替系統(tǒng)默認(rèn)失去。如果TZ定義為空串,則使用協(xié)調(diào)統(tǒng)一時(shí)間UTC。TZ的值常常類似于TX=EST5EDT。

總結(jié)

以上是生活随笔為你收集整理的UNIX环境高级编程-第六章-系统数据文件和信息的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。