fgets()函数

头文件:include<stdio.h>

fgets()函数

头文件:include<stdio.h>

fgets()函数用于从文件流中读取一行或指定个数的字符,其原型为:
    char * fgets(char * string, int size, FILE * stream);

参数说明:

· string为一个字符数组,用来保存读取到的字符。

· size为要读取的字符的个数。如果该行字符数大于size-1,则读到 size-1 个字符时结束,并在最后补充' \0';如果该行字符数小于等于 size-1,则读取所有字符,并在最后补充 '\0'。即,每次最多读取 size-1 个字符。

· stream为文件流指针。

【返回值】读取成功,返回读取到的字符串,即string;失败或读到文件结尾返回NULL。因此我们不能直接通过fgets()的返回值来判断函数是否是出错而终止的,应该借助feof()函数或者ferror()函数来判断。

注意:fgets()与gets()不一样,不仅仅是因为gets()函数只有一个参数 FILE *stream,更重要的是,fgets()可以指定最大读取的字符串的个数,杜绝了gets()使用不当造成缓存溢出的问题。

【实例】从myfile.txt文件中读取最多99个字符。

1. #include <stdio.h>

2.

3. int main()

4. {

5.     FILE * pFile;

6.     char mystring [100];

7.

8.     pFile = fopen ("myfile.txt" , "r");

9.     if (pFile == NULL)

10.         perror ("Error opening file");

11.     else {

12.         if ( fgets (mystring , 100 , pFile) != NULL )

13.             puts (mystring);

14.         fclose (pFile);

15.     }

16.     return 0;

17. }

又如,使用fputs()写一个文件,然后fgets()读取文件内容并显示。

1. #include <stdio.h>

2. #include<stdlib.h>

3. #include<io.h>

4. #include<conio.h>

5. int main(void)

6. {

7.     char msg[] = "This is a test!\n secend line\n";

8.     char msgget[100];

9.     int i = 0;

10.     FILE* fstream;

11.     fstream = fopen("test.txt","w+");        /*打开文件*/

12.     if(fstream==NULL)

13.     {

14.         printf("Open file failed!\n");

15.         exit(1);

16.     }

17.     fputs(msg, fstream);                /*写入文件*/

18.     fflush(fstream);

19.     close(fileno(fstream));

20.     fstream=fopen("test.txt","r");

21.     i = 0;

22.     fgets(msgget,3,fstream) ;

23.     fputs(msgget, stdout);

24.     printf("\n");

25.     fgets(msgget,100,fstream) ;/*从流中读取一行或者指定个数字符*/

26.     fputs(msgget, stdout); /*送一个字符串到流中*/

27.     return 0;

28. }

运行结果:
Th
is is a test!Fputs

C语言库函数 int fputs(const char *str, FILE *stream) 将一个字符串写入指定的流,但不包括空字符。

声明

以下是声明 fputs() 函数。

int fputs(const char *str, FILE *stream)

参数

·

str -- 这是一个数组,包含null结尾的要写入的字符序列。

·

·

stream -- 这是一个文件对象的标识字符串将被写入流的指针。

·

返回值

这个函数返回一个非负的值,否则,错误返回EOF。

例子

下面的例子显示的使用fputs() 函数。

#include <stdio.h>

int main (){

FILE *fp;

fp = fopen("file.txt", "w+");

fputs("This is c programming.", fp);

fputs("This is a system programming language.", fp);

fclose(fp);

return(0);}

让我们编译和运行上面的程序,这将创建一个文件file.txt 以下内容:

This is c programming.This is a system programming language.

关于重定向

I/O

cmd > file 把 stdout 重定向到 file 文件中;

cmd >> file 把 stdout 重定向到 file 文件中(追加);

cmd 1> file 把 stdout 重定向到 file 文件中;

cmd > file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中;

cmd 2> file 把 stderr 重定向到 file 文件中;

cmd 2>> file 把 stderr 重定向到 file 文件中(追加);

cmd >> file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中(追加);

cmd < file >file2 cmd 命令以 file 文件作为 stdin,以 file2 文件作为 stdout;

cat <>file 以读写的方式打开 file;

cmd < file cmd 命令以 file 文件作为 stdin;

cmd << delimiter Here document,从 stdin 中读入,直至遇到 delimiter 分界符。

进阶I/O

>&n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出;

<&n 标准输入复制自文件描述符 n;

<&- 关闭标准输入(键盘);

>&- 关闭标准输出;

n<&- 表示将 n 号输入关闭;

n>&- 表示将 n 号输出关闭;

上述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的 0 或 1。如:

... 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。

... 2>&1 运行一个命令并把它的标准输出和输出合并。(严格的说是通过复制文件描述符 1 来建立文件描述符 2 ,但效果通常是合并了两个流。)

我 们对 2>&1详细说明一下 :2>&1 也就是 FD2=FD1 ,这里并不是说FD2 的值 等于FD1的值,因为 > 是改变送出的数据通道,也就是说把 FD2 的 “数据输出通道” 改为 FD1 的 “数据输出通道”。如果仅仅这样,这个改变好像没有什么作用,因为 FD2 的默认输出和 FD1的默认输出本来都是 monitor,一样的! 但是,当 FD1 是其他文件,甚至是其他 FD 时,这个就具有特殊的用途了。请大家务必理解这一点。

exec 1>outfilename # 打开文件outfilename作为stdout。

exec 2>errfilename # 打开文件 errfilename作为 stderr。

exec 0<&- # 关闭 FD0。

exec 1>&- # 关闭 FD1。

exec 5>&- # 关闭 FD5。

Open()函数

相关函数:read, write, fcntl, close, link, stat, umask, unlink, fopen

头文件:#include <sys/types.h>    #include <sys/stat.h>    #include <fcntl.h>

定义函数:
    int open(const char * pathname, int flags);
    int open(const char * pathname, int flags, mode_t mode);

函数说明:

参数 pathname 指向欲打开的文件路径字符串. 下列是参数flags 所能使用的旗标:
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以可读写方式打开文件. 上述三种旗标是互斥的, 也就是不可同时使用, 但可与下列的旗标利用OR(|)运算符组合.
O_CREAT 若欲打开的文件不存在则自动建立该文件.
O_EXCL 如果O_CREAT 也被设置, 此指令会去检查文件是否存在. 文件若不存在则建立该文件, 否则将导致打开文件错误. 此外, 若O_CREAT 与O_EXCL 同时设置, 并且欲打开的文件为符号连接, 则会打开文件失败.
O_NOCTTY 如果欲打开的文件为终端机设备时, 则不会将该终端机当成进程控制终端机.
O_TRUNC 若文件存在并且以可写的方式打开时, 此旗标会令文件长度清为0, 而原来存于该文件的资料也会消失.
O_APPEND 当读写文件时会从文件尾开始移动, 也就是所写入的数据会以附加的方式加入到文件后面.
O_NONBLOCK 以不可阻断的方式打开文件, 也就是无论有无数据读取或等待, 都会立即返回进程之中.
O_NDELAY 同O_NONBLOCK.
O_SYNC 以同步的方式打开文件.
O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接, 则会令打开文件失败.
O_DIRECTORY 如果参数pathname 所指的文件并非为一目录, 则会令打开文件失败。注:此为Linux2. 2 以后特有的旗标, 以避免一些系统安全问题.

参数mode 则有下列数种组合, 只有在建立新文件时才会生效, 此外真正建文件时的权限会受到umask 值所影响, 因此该文件权限应该为 (mode-umaks).
S_IRWXU00700 权限, 代表该文件所有者具有可读、可写及可执行的权限.
S_IRUSR 或S_IREAD, 00400 权限, 代表该文件所有者具有可读取的权限.
S_IWUSR 或S_IWRITE, 00200 权限, 代表该文件所有者具有可写入的权限.
S_IXUSR 或S_IEXEC, 00100 权限, 代表该文件所有者具有可执行的权限.
S_IRWXG 00070 权限, 代表该文件用户组具有可读、可写及可执行的权限.
S_IRGRP 00040 权限, 代表该文件用户组具有可读的权限.
S_IWGRP 00020 权限, 代表该文件用户组具有可写入的权限.
S_IXGRP 00010 权限, 代表该文件用户组具有可执行的权限.
S_IRWXO 00007 权限, 代表其他用户具有可读、可写及可执行的权限.
S_IROTH 00004 权限, 代表其他用户具有可读的权限
S_IWOTH 00002 权限, 代表其他用户具有可写入的权限.
S_IXOTH 00001 权限, 代表其他用户具有可执行的权限.

返回值:若所有欲核查的权限都通过了检查则返回0 值, 表示成功, 只要有一个权限被禁止则返回-1.

错误代码:
EEXIST 参数pathname 所指的文件已存在, 却使用了O_CREAT 和O_EXCL 旗标.
EACCESS 参数pathname 所指的文件不符合所要求测试的权限.
EROFS 欲测试写入权限的文件存在于只读文件系统内.
EFAULT 参数pathname 指针超出可存取内存空间.
EINVAL 参数mode 不正确.
ENAMETOOLONG 参数 pathname 太长.
ENOTDIR 参数pathname 不是目录.
ENOMEM 核心内存不足.
ELOOP 参数pathname 有过多符号连接问题.
EIO I/O 存取错误.

附加说明:使用 access()作用户认证方面的判断要特别小心, 例如在access()后再作open()空文件可能会造成系统安全上的问题.

范例
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
main()
{
    int fd, size;
    char s[] = "Linux Programmer!\n", buffer[80];
    fd = open("/tmp/temp", O_WRONLY|O_CREAT);
    write(fd, s, sizeof(s));
    close(fd);
    fd = open("/tmp/temp", O_RDONLY);
    size = read(fd, buffer, sizeof(buffer));
    close(fd);
    printf("%s", buffer);
}

执行
Linux Programmer!

C语言read()函数:读文件函数(由已打开的文件读取数据)

C语言中文网教程编写,诚邀您的加入!

C语言中文网VIP会员:低至19.9元/月,阅读所有高级教程,还有1T资料赠送!

相关函数:readdir, write, fcntl, close, lseek, readlink, fread

头文件:#include <unistd.h>

定义函数:ssize_t read(int fd, void * buf, size_t count);

函数说明:read()会把参数fd 所指的文件传送count 个字节到buf 指针所指的内存中. 若参数count 为0, 则read()不会有作用并返回0. 返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动.

附加说明:
如果顺利 read()会返回实际读到的字节数, 最好能将返回值与参数count 作比较, 若返回的字节数比要求读取的字节数少, 则有可能读到了文件尾、从管道(pipe)或终端机读? ?蛘呤莚ead()被信号中断了读取动作.

当有错误发生时则返回-1, 错误代码存入errno 中, 而文件读写位置则无法预期.

错误代码:
EINTR 此调用被信号所中断.
EAGAIN 当使用不可阻断I/O 时(O_NONBLOCK), 若无数据可读取则返回此值.
EBADF 参数fd 非有效的文件描述词, 或该文件已关闭.

1.Write函数

用法:  
#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

参数:   
fd:要进行写操作的文件描述词。
buf:需要输出的缓冲区
count:最大输出字节计数

使用时候偶然发现,如果设置打开fb=open("/dev/fb0",O_RDONLY)之类的缓存文件,并且再打开fb_tupian=open("tu.bin",O_RDONLY);并且将fb_tupian使用read(fb_tupian,buf,size);读取之后,这个buf存放的就是tu.bin的数据

好了,问题出现了,当使用write(fb,buf,size)写第一张图片的时候还是正确的,但是当打开例如:tu001.bin的buf001,发现,不能写入framebuffer的fb文件描述符下,因为由于前面写的tu.bin的数据已经导致缓存地址溢出,因此,后面的图片再次使用write函数写入到fb的时候,fb缓存的地址没有清到缓存的首地址,因此溢出了LCD屏幕范围。

解决的方法是:需要将该文件close掉,再次打开,才能进行重写。

2.fread函数和fwrite函数

1.函数功能

用来读写一个数据块。

2.一般调用形式

fread(buffer,size,count,fp);

fwrite(buffer,size,count,fp);

3.说明

(1)buffer:是一个指针,对fread来说,它是读入数据的存放地址。对fwrite来说,是要输出数据的地址。

(2)size:要读写的字节数;

(3)count:要进行读写多少个size字节的数据项;

(4)fp:文件型指针。

头文件:#include <stdio.h>

定义函数:size_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream);

函数说明:fread()用来从文件流中读取数据.

参数stream 为已打开的文件指针, 参数ptr 指向欲存放读取进来的数据空间, 读取的字符数以参数size*nmemb 来决定. Fread()会返回实际读取到的nmemb 数目, 如果此值比参数nmemb 来得小, 则代表可能读到了文件的尾或有错误发生, 这时必须用feof()或ferror()来决定发生什么情况.

返回值:返回实际读取到的nmemb 数目。

范例
#include <stdio.h>
#define nmemb 3
struct test
{
    char name[20];
    int size;
} s[nmemb];

main()
{
    FILE * stream;
    int i;
    stream = fopen("/tmp/fwrite", "r");
    fread(s, sizeof(struct test), nmemb, stream);
    fclose(stream);
    for(i = 0; i < nmemb; i++)
        printf("name[%d]=%-20s:size[%d]=%d\n", i, s[i].name, i, s[i].size);
}

执行
name[0]=Linux! size[0]=6
name[1]=FreeBSD! size[1]=8
name[2]=Windows2000 size[2]=11

头文件:#include <stdio.h>

fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为:
    FILE * fopen(const char * path, const char * mode);

【参数】path为包含了路径的文件名,mode为文件打开方式。

mode有以下几种方式:

打开方式

说明

r

以只读方式打开文件,该文件必须存在。

r+

以读/写方式打开文件,该文件必须存在。

rb+

以读/写方式打开一个二进制文件,只允许读/写数据。

rt+

以读/写方式打开一个文本文件,允许读和写。

w

打开只写文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。

w+

打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

a

以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。

a+

以附加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。

wb

以只写方式打开或新建一个二进制文件,只允许写数据。

wb+

以读/写方式打开或建立一个二进制文件,允许读和写。

wt+

以读/写方式打开或建立一个文本文件,允许读写。

at+

以读/写方式打开一个文本文件,允许读或在文本末追加数据。

ab+

以读/写方式打开一个二进制文件,允许读或在文件末追加数据。

在POSIX 系统,包含Linux 下都会忽略 b 字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。

二进制和文本模式的区别:

· 在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。

· 在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。

更多信息请查看:C语言fopen()打开文本文件与二进制文件的区别

有些C编译系统可能不完全提供所有这些功能,有的C版本不用"r+","w+","a+",而用"rw","wr","ar"等,读者注意所用系统的规定。

【返回值】文件顺利打开后,指向该流的文件指针就会被返回。若果文件打开失败则返回NULL,并把错误代码存在errno 中。

注意:一般而言,开文件后会作一些文件读取或写入的动作,若开文件失败,接下来的读写动作也无法顺利进行,所以在fopen()后请作错误判断及处理。

文件操作完成后,需要将文件关闭,一定要注意,否则会造成文件所占用内存泄露和在下次访问文件时出现问题。

文件关闭后,需要将文件指针指向空,这样做会防止出现游离指针,而对整个工程造成不必要的麻烦,如fp = NULL。

【实例】打开一个文件然后关闭该文件。

1. #include<stdio.h>

2. #include<string.h>

3. #include<stdlib.h>

4. int main()

5. {

6.

7.     FILE* fstream;

8.     char msg[100] = "Hello!I have read this file.";

9.     fstream=fopen("test.txt","at+");

10.     if(fstream==NULL)

11.     {

12.         printf("open file test.txt failed!\n");

13.         exit(1);

14.     }

15.     else

16.     {

17.         printf("open file test.txt succeed!\n");

18.     }

19.     fclose(fstream);

20.     return 0;

21. }

Opendir

相关函数:open, readdir, closedir, rewinddir, seekdir, telldir, scandir

头文件:#include <sys/types.h>   #include <dirent.h>

定义函数:DIR * opendir(const char * name);

函数说明:opendir()用来打开参数name 指定的目录, 并返回DIR*形态的目录流, 和open()类似, 接下来对目录的读取和搜索都要使用此返回值.

返回值:成功则返回DIR* 型态的目录流, 打开失败则返回NULL.

错误代码:
1、EACCESS 权限不足。
2、EMFILE 已达到进程可同时打开的文件数上限。
3、ENFILE 已达到系统可同时打开的文件数上限。
4、ENOTDIR 参数name 非真正的目录。
5、ENOENT 参数name 指定的目录不存在, 或是参数name 为一空字符串。
6、ENOMEM 核心内存不足。

readdir()函数

相关函数:open, opendir, closedir, rewinddir, seekdir, telldir, scandir

头文件:#include <sys/types.h>   #include <dirent.h>

定义函数:struct dirent * readdir(DIR * dir);

函数说明:readdir()返回参数dir 目录流的下个目录进入点。结构dirent 定义如下:
struct dirent
{
    ino_t d_ino; //d_ino 此目录进入点的inode
    ff_t d_off; //d_off 目录文件开头至此目录进入点的位移
    signed short int d_reclen; //d_reclen _name 的长度, 不包含NULL 字符
    unsigned char d_type; //d_type d_name 所指的文件类型 d_name 文件名
    har d_name[256];
};

返回值:成功则返回下个目录进入点. 有错误发生或读取到目录文件尾则返回NULL.

附加说明:EBADF 参数dir 为无效的目录流。

范例
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
main()
{
    DIR * dir;
    struct dirent * ptr;
    int i;
    dir = opendir("/etc/rc.d");
    while((ptr = readdir(dir)) != NULL)
    {
        printf("d_name : %s\n", ptr->d_name);
    }
    closedir(dir);
}
执行:
d_name : .
d_name : ..
d_name : init.d
d_name : rc0.d
d_name : rc1.d
d_name : rc2.d
d_name : rc3.d
d_name : rc4.d
d_name : rc5.d
d_name : rc6.d
d_name : rc
d_name : rc.local
d_name : rc.sysinit

头文件:#include <time.h>

定义函数:time_t time(time_t *t);

函数说明:此函数会返回从公元 1970 年1 月1 日的UTC 时间从0 时0 分0 秒算起到现在所经过的秒数。如果t 并非空指针的话,此函数也会将返回值存到t 指针所指的内存。

返回值:成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno 中。

范例

1. #include <time.h>

2. main(){

3.     int seconds = time((time_t*)NULL);

4.     printf("%d\n", seconds);

5. }

执行结果:
9.73E+08

头文件:#include <time.h>

定义函数:char *ctime(const time_t *timep);

函数说明:ctime()将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为"Wed Jun 30 21 :49 :08 1993\n"。

注意:若再调用相关的时间日期函数,此字符串可能会被破坏。

返回值:返回一字符串表示目前当地的时间日期。

范例

1. #include <time.h>

2. main(){

3.     time_t timep;

4.     time (&timep);

5.     printf("%s", ctime(&timep));

6. }

执行
Sat Oct 28 10 : 12 : 05 2000

头文件:#include <time.h>

定义函数:struct tm *gmtime(const time_t *timep);

函数说明:gmtime()将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm 返回。

结构tm 的定义为

1. struct tm{

2.     int tm_sec;  //代表目前秒数, 正常范围为0-59, 但允许至61 秒

3.     int tm_min;  //代表目前分数, 范围0-59

4.     int tm_hour;  //从午夜算起的时数, 范围为0-23

5.     int tm_mday;  //目前月份的日数, 范围01-31

6.     int tm_mon;  //代表目前月份, 从一月算起, 范围从0-11

7.     int tm_year;  //从1900 年算起至今的年数

8.     int tm_wday;  //一星期的日数, 从星期一算起, 范围为0-6

9.     int tm_yday;  //从今年1 月1 日算起至今的天数, 范围为0-365

10.     int tm_isdst;  //日光节约时间的旗标

11. };

此函数返回的时间日期未经时区转换,而是UTC 时间。

返回值:返回结构tm 代表目前UTC 时间。

范例

1. #include <time.h>

2. main(){

3.     char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

4.     time_t timep;

5.     struct tm *p;

6.     time(&timep);

7.     p = gmtime(&timep);

8.     printf("%d%d%d", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday);

9.     printf("%s%d;%d;%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);

10. }

执行结果:
2000/10/28 Sat 8:15:38

相关函数:time, ctime, gmtime, localtime

头文件:#include <time.h>

定义函数:char *asctime(const struct tm * timeptr);

函数说明:asctime()将参数timeptr 所指的tm 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为:"Wed Jun 30 21:49:08 1993\n"

返回值:若再调用相关的时间日期函数,此字符串可能会被破坏。此函数与ctime 不同处在于传入的参数是不同的结构。

附加说明:返回一字符串表示目前当地的时间日期.

范例

1. #include <time.h>

2. main(){

3.     time_t timep;

4.     time (&timep);

5.     printf("%s", asctime(gmtime(&timep)));

6. }

执行
Sat Oct 28 02:10:06 2000

相关函数:get_current_dir_name, getwd, chdir

clock_t定义

在time.h文件中,我们可以找到对它的定义:

#ifndef _CLOCK_T_DEFINED

typedef long clock_t;

#define _CLOCK_T_DEFINED

#endif

很明显,clock_t是一个长整形数。在time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:

#define CLOCKS_PER_SEC ((clock_t)1000)

在linux系统下,CLOCKS_PER_SEC的值可能有所不同,目前使用的linux打印出来的值是1000000,表示的是微秒。这一点需要注意。

可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。下面举个例子,你可以使用公式clock()/CLOCKS_PER_SEC来计算一个进程自身的运行时间:

void elapsed_time()

{

printf("Elapsed time:%u secs.\n",clock()/CLOCKS_PER_SEC);

}

当然,你也可以用clock函数来计算你的机器运行一个循环或者处理其它事件到底花了多少时间:

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

int main(void)

{

long i = 10000000L;

clock_t start, finish;

double duration;

/* 测量一个事件持续的时间*/

printf( "Time to do %ld empty loops is ", i) ;

start = clock();

while( i-- );

finish = clock();

duration = (double)(finish - start) / CLOCKS_PER_SEC;

printf( "%f seconds\n", duration );

system("pause");

}

运行结果

Time to do 10000000 empty loops is 0.03000 seconds

上面我们看到时钟计时单元的长度为1毫秒,那么计时的精度也为1毫秒,那么我们可不可以通过改变CLOCKS_PER_SEC的定义,通过把它定义的大一些,从而使计时精度更高呢?通过尝试,你会发现这样是不行的。在标准C/C++中,最小的计时单位是一毫秒。

getcwd()函数
头文件:#include <unistd.h>

定义函数:char * getcwd(char * buf, size_t size);

函数说明:getcwd()会将当前的工作目录绝对路径复制到参数buf 所指的内存空间,参数size 为buf 的空间大小。

注:
1、在调用此函数时,buf 所指的内存空间要足够大。若工作目录绝对路径的字符串长度超过参数size 大小,则返回NULL,errno 的值则为ERANGE。
2、倘若参数buf 为NULL,getcwd()会依参数size 的大小自动配置内存(使用malloc()),如果参数size 也为0,则getcwd()会依工作目录绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用完次字符串后利用free()来释放此空间。

返回值:执行成功则将结果复制到参数buf 所指的内存空间, 或是返回自动配置的字符串指针. 失败返回NULL,错误代码存于errno.

范例
#include <unistd.h>
main()
{
    char buf[80];
    getcwd(buf, sizeof(buf));
    printf("current working directory : %s\n", buf);
}

执行:
current working directory :/tmp

Mkdir()函数

mkdir的函数原型(使用时需包含#include <sys/stat.h>):

int mkdir(const char *path, mode_t mode);

参数:

path——目录名,比如abc,/var/www/abc等

mode——目录权限

返回值:

返回0 表示成功, 返回 -1表示错误,并且会设置errno值。

关于Mode定义,请参考:http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysstat.h.html

当然你也可以不用那些类似S_IRWXU、S_IRUSR...类似的宏参数,毕竟很难记忆,反倒不如8进制的0421好记。组合样式为:owner-group-others,不同人都分三个规则读-写-执行(r-w-x),全部许可就是7。

1、编程时使用mkdir("test",777)报错 
试一下:

mkdir("test",0777);

写成mkdir("test",777)有可能无法执行。但是依稀记得,以前都是用777的也没错误,具体忘记了,反正按照规范写绝对没错。

2、umask命令使用 
另外假设你的程序目录在/root/abc/下,那么如果你的程序执行时想在/var/www下创建目录时,有可能你始终创建一个0777的目录总是创建成0755目录,这时可以尝试使用umask(0)命令。

umask只对当前目录有效,默认umask值为0022,所以你无法在另外一个地方直接创建0777的目录。

而是0777-0022=0755

3、如何创建某个用户组的文件夹 
/etc/passwd和/etc/group找到UID和gid

mkdir /var/ugroup

我们可以直接使用chown来改变文件所有者。

chown root:newuser /var/ugroup

修改权限

chmod 740 /var/ugroup/*

4、察看创建后目录权限情况命令: 
定位到该用户组目录下,执行:

ls -all

会显示类似:

drwxrwxr-x

这样的结果(0775)。

头文件:#include <stdio.h>

remove()函数用于删除指定的文件,其原型如下:
    int remove(char * filename);

【参数】filename为要删除的文件名,可以为一目录。如果参数filename 为一文件,则调用unlink()处理;若参数filename 为一目录,则调用rmdir()来处理。

【返回值】成功则返回0,失败则返回-1,错误原因存于errno。

错误代码:

1. EROFS  欲写入的文件为只读文件。

2. EFAULT  参数filename 指针超出可存取内存空间。

3. ENAMETOOLONG  参数filename 太长。

4. ENOMEM  核心内存不足。

5. ELOOP  参数filename 有过多符号连接问题。

6. EIO I/O  存取错误。

【实例】下面的程序演示了如何使用remove()函数删除文件。

1. #include<stdio.h>

2. int main(){

3.     char filename[80];

4.     printf("The file to delete:");

5.     gets(filename);

6.     if( remove(filename) == 0 )

7.         printf("Removed %s.", filename);

8.     else

9.         perror("remove");

10. }

运行上述程序,首先声明用于保存文件名的字符数组变量,从控制台获取文件名,然后删除该文件,并根据删除结果输出相应的提示信息。

fgets()函数用于从文件流中读取一行或指定个数的字符,其原型为:
    char * fgets(char * string, int size, FILE * stream);

参数说明:

· string为一个字符数组,用来保存读取到的字符。

· size为要读取的字符的个数。如果该行字符数大于size-1,则读到 size-1 个字符时结束,并在最后补充' \0';如果该行字符数小于等于 size-1,则读取所有字符,并在最后补充 '\0'。即,每次最多读取 size-1 个字符。

· stream为文件流指针。

【返回值】读取成功,返回读取到的字符串,即string;失败或读到文件结尾返回NULL。因此我们不能直接通过fgets()的返回值来判断函数是否是出错而终止的,应该借助feof()函数或者ferror()函数来判断。

注意:fgets()与gets()不一样,不仅仅是因为gets()函数只有一个参数 FILE *stream,更重要的是,fgets()可以指定最大读取的字符串的个数,杜绝了gets()使用不当造成缓存溢出的问题。

【实例】从myfile.txt文件中读取最多99个字符。

1. #include <stdio.h>

2.

3. int main()

4. {

5.     FILE * pFile;

6.     char mystring [100];

7.

8.     pFile = fopen ("myfile.txt" , "r");

9.     if (pFile == NULL)

10.         perror ("Error opening file");

11.     else {

12.         if ( fgets (mystring , 100 , pFile) != NULL )

13.             puts (mystring);

14.         fclose (pFile);

15.     }

16.     return 0;

17. }

又如,使用fputs()写一个文件,然后fgets()读取文件内容并显示。

1. #include <stdio.h>

2. #include<stdlib.h>

3. #include<io.h>

4. #include<conio.h>

5. int main(void)

6. {

7.     char msg[] = "This is a test!\n secend line\n";

8.     char msgget[100];

9.     int i = 0;

10.     FILE* fstream;

11.     fstream = fopen("test.txt","w+");        /*打开文件*/

12.     if(fstream==NULL)

13.     {

14.         printf("Open file failed!\n");

15.         exit(1);

16.     }

17.     fputs(msg, fstream);                /*写入文件*/

18.     fflush(fstream);

19.     close(fileno(fstream));

20.     fstream=fopen("test.txt","r");

21.     i = 0;

22.     fgets(msgget,3,fstream) ;

23.     fputs(msgget, stdout);

24.     printf("\n");

25.     fgets(msgget,100,fstream) ;/*从流中读取一行或者指定个数字符*/

26.     fputs(msgget, stdout); /*送一个字符串到流中*/

27.     return 0;

28. }

运行结果:
Th
is is a test!Fputs

C语言库函数 int fputs(const char *str, FILE *stream) 将一个字符串写入指定的流,但不包括空字符。

声明

以下是声明 fputs() 函数。

int fputs(const char *str, FILE *stream)

参数

·

str -- 这是一个数组,包含null结尾的要写入的字符序列。

·

·

stream -- 这是一个文件对象的标识字符串将被写入流的指针。

·

返回值

这个函数返回一个非负的值,否则,错误返回EOF。

例子

下面的例子显示的使用fputs() 函数。

#include <stdio.h>

int main (){

FILE *fp;

fp = fopen("file.txt", "w+");

fputs("This is c programming.", fp);

fputs("This is a system programming language.", fp);

fclose(fp);

return(0);}

让我们编译和运行上面的程序,这将创建一个文件file.txt 以下内容:

This is c programming.This is a system programming language.

关于重定向

I/O

cmd > file 把 stdout 重定向到 file 文件中;

cmd >> file 把 stdout 重定向到 file 文件中(追加);

cmd 1> file 把 stdout 重定向到 file 文件中;

cmd > file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中;

cmd 2> file 把 stderr 重定向到 file 文件中;

cmd 2>> file 把 stderr 重定向到 file 文件中(追加);

cmd >> file 2>&1 把 stdout 和 stderr 一起重定向到 file 文件中(追加);

cmd < file >file2 cmd 命令以 file 文件作为 stdin,以 file2 文件作为 stdout;

cat <>file 以读写的方式打开 file;

cmd < file cmd 命令以 file 文件作为 stdin;

cmd << delimiter Here document,从 stdin 中读入,直至遇到 delimiter 分界符。

进阶I/O

>&n 使用系统调用 dup (2) 复制文件描述符 n 并把结果用作标准输出;

<&n 标准输入复制自文件描述符 n;

<&- 关闭标准输入(键盘);

>&- 关闭标准输出;

n<&- 表示将 n 号输入关闭;

n>&- 表示将 n 号输出关闭;

上述所有形式都可以前导一个数字,此时建立的文件描述符由这个数字指定而不是缺省的 0 或 1。如:

... 2>file 运行一个命令并把错误输出(文件描述符 2)定向到 file。

... 2>&1 运行一个命令并把它的标准输出和输出合并。(严格的说是通过复制文件描述符 1 来建立文件描述符 2 ,但效果通常是合并了两个流。)

我 们对 2>&1详细说明一下 :2>&1 也就是 FD2=FD1 ,这里并不是说FD2 的值 等于FD1的值,因为 > 是改变送出的数据通道,也就是说把 FD2 的 “数据输出通道” 改为 FD1 的 “数据输出通道”。如果仅仅这样,这个改变好像没有什么作用,因为 FD2 的默认输出和 FD1的默认输出本来都是 monitor,一样的! 但是,当 FD1 是其他文件,甚至是其他 FD 时,这个就具有特殊的用途了。请大家务必理解这一点。

exec 1>outfilename # 打开文件outfilename作为stdout。

exec 2>errfilename # 打开文件 errfilename作为 stderr。

exec 0<&- # 关闭 FD0。

exec 1>&- # 关闭 FD1。

exec 5>&- # 关闭 FD5。

Open()函数

相关函数:read, write, fcntl, close, link, stat, umask, unlink, fopen

头文件:#include <sys/types.h>    #include <sys/stat.h>    #include <fcntl.h>

定义函数:
    int open(const char * pathname, int flags);
    int open(const char * pathname, int flags, mode_t mode);

函数说明:

参数 pathname 指向欲打开的文件路径字符串. 下列是参数flags 所能使用的旗标:
O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR 以可读写方式打开文件. 上述三种旗标是互斥的, 也就是不可同时使用, 但可与下列的旗标利用OR(|)运算符组合.
O_CREAT 若欲打开的文件不存在则自动建立该文件.
O_EXCL 如果O_CREAT 也被设置, 此指令会去检查文件是否存在. 文件若不存在则建立该文件, 否则将导致打开文件错误. 此外, 若O_CREAT 与O_EXCL 同时设置, 并且欲打开的文件为符号连接, 则会打开文件失败.
O_NOCTTY 如果欲打开的文件为终端机设备时, 则不会将该终端机当成进程控制终端机.
O_TRUNC 若文件存在并且以可写的方式打开时, 此旗标会令文件长度清为0, 而原来存于该文件的资料也会消失.
O_APPEND 当读写文件时会从文件尾开始移动, 也就是所写入的数据会以附加的方式加入到文件后面.
O_NONBLOCK 以不可阻断的方式打开文件, 也就是无论有无数据读取或等待, 都会立即返回进程之中.
O_NDELAY 同O_NONBLOCK.
O_SYNC 以同步的方式打开文件.
O_NOFOLLOW 如果参数pathname 所指的文件为一符号连接, 则会令打开文件失败.
O_DIRECTORY 如果参数pathname 所指的文件并非为一目录, 则会令打开文件失败。注:此为Linux2. 2 以后特有的旗标, 以避免一些系统安全问题.

参数mode 则有下列数种组合, 只有在建立新文件时才会生效, 此外真正建文件时的权限会受到umask 值所影响, 因此该文件权限应该为 (mode-umaks).
S_IRWXU00700 权限, 代表该文件所有者具有可读、可写及可执行的权限.
S_IRUSR 或S_IREAD, 00400 权限, 代表该文件所有者具有可读取的权限.
S_IWUSR 或S_IWRITE, 00200 权限, 代表该文件所有者具有可写入的权限.
S_IXUSR 或S_IEXEC, 00100 权限, 代表该文件所有者具有可执行的权限.
S_IRWXG 00070 权限, 代表该文件用户组具有可读、可写及可执行的权限.
S_IRGRP 00040 权限, 代表该文件用户组具有可读的权限.
S_IWGRP 00020 权限, 代表该文件用户组具有可写入的权限.
S_IXGRP 00010 权限, 代表该文件用户组具有可执行的权限.
S_IRWXO 00007 权限, 代表其他用户具有可读、可写及可执行的权限.
S_IROTH 00004 权限, 代表其他用户具有可读的权限
S_IWOTH 00002 权限, 代表其他用户具有可写入的权限.
S_IXOTH 00001 权限, 代表其他用户具有可执行的权限.

返回值:若所有欲核查的权限都通过了检查则返回0 值, 表示成功, 只要有一个权限被禁止则返回-1.

错误代码:
EEXIST 参数pathname 所指的文件已存在, 却使用了O_CREAT 和O_EXCL 旗标.
EACCESS 参数pathname 所指的文件不符合所要求测试的权限.
EROFS 欲测试写入权限的文件存在于只读文件系统内.
EFAULT 参数pathname 指针超出可存取内存空间.
EINVAL 参数mode 不正确.
ENAMETOOLONG 参数 pathname 太长.
ENOTDIR 参数pathname 不是目录.
ENOMEM 核心内存不足.
ELOOP 参数pathname 有过多符号连接问题.
EIO I/O 存取错误.

附加说明:使用 access()作用户认证方面的判断要特别小心, 例如在access()后再作open()空文件可能会造成系统安全上的问题.

范例
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
main()
{
    int fd, size;
    char s[] = "Linux Programmer!\n", buffer[80];
    fd = open("/tmp/temp", O_WRONLY|O_CREAT);
    write(fd, s, sizeof(s));
    close(fd);
    fd = open("/tmp/temp", O_RDONLY);
    size = read(fd, buffer, sizeof(buffer));
    close(fd);
    printf("%s", buffer);
}

执行
Linux Programmer!

C语言read()函数:读文件函数(由已打开的文件读取数据)

C语言中文网教程编写,诚邀您的加入!

C语言中文网VIP会员:低至19.9元/月,阅读所有高级教程,还有1T资料赠送!

相关函数:readdir, write, fcntl, close, lseek, readlink, fread

头文件:#include <unistd.h>

定义函数:ssize_t read(int fd, void * buf, size_t count);

函数说明:read()会把参数fd 所指的文件传送count 个字节到buf 指针所指的内存中. 若参数count 为0, 则read()不会有作用并返回0. 返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据,此外文件读写位置会随读取到的字节移动.

附加说明:
如果顺利 read()会返回实际读到的字节数, 最好能将返回值与参数count 作比较, 若返回的字节数比要求读取的字节数少, 则有可能读到了文件尾、从管道(pipe)或终端机读? ?蛘呤莚ead()被信号中断了读取动作.

当有错误发生时则返回-1, 错误代码存入errno 中, 而文件读写位置则无法预期.

错误代码:
EINTR 此调用被信号所中断.
EAGAIN 当使用不可阻断I/O 时(O_NONBLOCK), 若无数据可读取则返回此值.
EBADF 参数fd 非有效的文件描述词, 或该文件已关闭.

1.Write函数

用法:  
#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);

参数:   
fd:要进行写操作的文件描述词。
buf:需要输出的缓冲区
count:最大输出字节计数

使用时候偶然发现,如果设置打开fb=open("/dev/fb0",O_RDONLY)之类的缓存文件,并且再打开fb_tupian=open("tu.bin",O_RDONLY);并且将fb_tupian使用read(fb_tupian,buf,size);读取之后,这个buf存放的就是tu.bin的数据

好了,问题出现了,当使用write(fb,buf,size)写第一张图片的时候还是正确的,但是当打开例如:tu001.bin的buf001,发现,不能写入framebuffer的fb文件描述符下,因为由于前面写的tu.bin的数据已经导致缓存地址溢出,因此,后面的图片再次使用write函数写入到fb的时候,fb缓存的地址没有清到缓存的首地址,因此溢出了LCD屏幕范围。

解决的方法是:需要将该文件close掉,再次打开,才能进行重写。

2.fread函数和fwrite函数

1.函数功能

用来读写一个数据块。

2.一般调用形式

fread(buffer,size,count,fp);

fwrite(buffer,size,count,fp);

3.说明

(1)buffer:是一个指针,对fread来说,它是读入数据的存放地址。对fwrite来说,是要输出数据的地址。

(2)size:要读写的字节数;

(3)count:要进行读写多少个size字节的数据项;

(4)fp:文件型指针。

头文件:#include <stdio.h>

定义函数:size_t fread(void * ptr, size_t size, size_t nmemb, FILE * stream);

函数说明:fread()用来从文件流中读取数据.

参数stream 为已打开的文件指针, 参数ptr 指向欲存放读取进来的数据空间, 读取的字符数以参数size*nmemb 来决定. Fread()会返回实际读取到的nmemb 数目, 如果此值比参数nmemb 来得小, 则代表可能读到了文件的尾或有错误发生, 这时必须用feof()或ferror()来决定发生什么情况.

返回值:返回实际读取到的nmemb 数目。

范例
#include <stdio.h>
#define nmemb 3
struct test
{
    char name[20];
    int size;
} s[nmemb];

main()
{
    FILE * stream;
    int i;
    stream = fopen("/tmp/fwrite", "r");
    fread(s, sizeof(struct test), nmemb, stream);
    fclose(stream);
    for(i = 0; i < nmemb; i++)
        printf("name[%d]=%-20s:size[%d]=%d\n", i, s[i].name, i, s[i].size);
}

执行
name[0]=Linux! size[0]=6
name[1]=FreeBSD! size[1]=8
name[2]=Windows2000 size[2]=11

头文件:#include <stdio.h>

fopen()是一个常用的函数,用来以指定的方式打开文件,其原型为:
    FILE * fopen(const char * path, const char * mode);

【参数】path为包含了路径的文件名,mode为文件打开方式。

mode有以下几种方式:

打开方式

说明

r

以只读方式打开文件,该文件必须存在。

r+

以读/写方式打开文件,该文件必须存在。

rb+

以读/写方式打开一个二进制文件,只允许读/写数据。

rt+

以读/写方式打开一个文本文件,允许读和写。

w

打开只写文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。

w+

打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

a

以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。

a+

以附加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。

wb

以只写方式打开或新建一个二进制文件,只允许写数据。

wb+

以读/写方式打开或建立一个二进制文件,允许读和写。

wt+

以读/写方式打开或建立一个文本文件,允许读写。

at+

以读/写方式打开一个文本文件,允许读或在文本末追加数据。

ab+

以读/写方式打开一个二进制文件,允许读或在文件末追加数据。

在POSIX 系统,包含Linux 下都会忽略 b 字符。由fopen()所建立的新文件会具有S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH(0666)权限,此文件权限也会参考umask 值。

二进制和文本模式的区别:

· 在windows系统中,文本模式下,文件以"\r\n"代表换行。若以文本模式打开文件,并用fputs等函数写入换行符"\n"时,函数会自动在"\n"前面加上"\r"。即实际写入文件的是"\r\n" 。

· 在类Unix/Linux系统中文本模式下,文件以"\n"代表换行。所以Linux系统中在文本模式和二进制模式下并无区别。

更多信息请查看:C语言fopen()打开文本文件与二进制文件的区别

有些C编译系统可能不完全提供所有这些功能,有的C版本不用"r+","w+","a+",而用"rw","wr","ar"等,读者注意所用系统的规定。

【返回值】文件顺利打开后,指向该流的文件指针就会被返回。若果文件打开失败则返回NULL,并把错误代码存在errno 中。

注意:一般而言,开文件后会作一些文件读取或写入的动作,若开文件失败,接下来的读写动作也无法顺利进行,所以在fopen()后请作错误判断及处理。

文件操作完成后,需要将文件关闭,一定要注意,否则会造成文件所占用内存泄露和在下次访问文件时出现问题。

文件关闭后,需要将文件指针指向空,这样做会防止出现游离指针,而对整个工程造成不必要的麻烦,如fp = NULL。

【实例】打开一个文件然后关闭该文件。

1. #include<stdio.h>

2. #include<string.h>

3. #include<stdlib.h>

4. int main()

5. {

6.

7.     FILE* fstream;

8.     char msg[100] = "Hello!I have read this file.";

9.     fstream=fopen("test.txt","at+");

10.     if(fstream==NULL)

11.     {

12.         printf("open file test.txt failed!\n");

13.         exit(1);

14.     }

15.     else

16.     {

17.         printf("open file test.txt succeed!\n");

18.     }

19.     fclose(fstream);

20.     return 0;

21. }

Opendir

相关函数:open, readdir, closedir, rewinddir, seekdir, telldir, scandir

头文件:#include <sys/types.h>   #include <dirent.h>

定义函数:DIR * opendir(const char * name);

函数说明:opendir()用来打开参数name 指定的目录, 并返回DIR*形态的目录流, 和open()类似, 接下来对目录的读取和搜索都要使用此返回值.

返回值:成功则返回DIR* 型态的目录流, 打开失败则返回NULL.

错误代码:
1、EACCESS 权限不足。
2、EMFILE 已达到进程可同时打开的文件数上限。
3、ENFILE 已达到系统可同时打开的文件数上限。
4、ENOTDIR 参数name 非真正的目录。
5、ENOENT 参数name 指定的目录不存在, 或是参数name 为一空字符串。
6、ENOMEM 核心内存不足。

readdir()函数

相关函数:open, opendir, closedir, rewinddir, seekdir, telldir, scandir

头文件:#include <sys/types.h>   #include <dirent.h>

定义函数:struct dirent * readdir(DIR * dir);

函数说明:readdir()返回参数dir 目录流的下个目录进入点。结构dirent 定义如下:
struct dirent
{
    ino_t d_ino; //d_ino 此目录进入点的inode
    ff_t d_off; //d_off 目录文件开头至此目录进入点的位移
    signed short int d_reclen; //d_reclen _name 的长度, 不包含NULL 字符
    unsigned char d_type; //d_type d_name 所指的文件类型 d_name 文件名
    har d_name[256];
};

返回值:成功则返回下个目录进入点. 有错误发生或读取到目录文件尾则返回NULL.

附加说明:EBADF 参数dir 为无效的目录流。

范例
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
main()
{
    DIR * dir;
    struct dirent * ptr;
    int i;
    dir = opendir("/etc/rc.d");
    while((ptr = readdir(dir)) != NULL)
    {
        printf("d_name : %s\n", ptr->d_name);
    }
    closedir(dir);
}
执行:
d_name : .
d_name : ..
d_name : init.d
d_name : rc0.d
d_name : rc1.d
d_name : rc2.d
d_name : rc3.d
d_name : rc4.d
d_name : rc5.d
d_name : rc6.d
d_name : rc
d_name : rc.local
d_name : rc.sysinit

头文件:#include <time.h>

定义函数:time_t time(time_t *t);

函数说明:此函数会返回从公元 1970 年1 月1 日的UTC 时间从0 时0 分0 秒算起到现在所经过的秒数。如果t 并非空指针的话,此函数也会将返回值存到t 指针所指的内存。

返回值:成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno 中。

范例

1. #include <time.h>

2. main(){

3.     int seconds = time((time_t*)NULL);

4.     printf("%d\n", seconds);

5. }

执行结果:
9.73E+08

头文件:#include <time.h>

定义函数:char *ctime(const time_t *timep);

函数说明:ctime()将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为"Wed Jun 30 21 :49 :08 1993\n"。

注意:若再调用相关的时间日期函数,此字符串可能会被破坏。

返回值:返回一字符串表示目前当地的时间日期。

范例

1. #include <time.h>

2. main(){

3.     time_t timep;

4.     time (&timep);

5.     printf("%s", ctime(&timep));

6. }

执行
Sat Oct 28 10 : 12 : 05 2000

头文件:#include <time.h>

定义函数:struct tm *gmtime(const time_t *timep);

函数说明:gmtime()将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果由结构tm 返回。

结构tm 的定义为

1. struct tm{

2.     int tm_sec;  //代表目前秒数, 正常范围为0-59, 但允许至61 秒

3.     int tm_min;  //代表目前分数, 范围0-59

4.     int tm_hour;  //从午夜算起的时数, 范围为0-23

5.     int tm_mday;  //目前月份的日数, 范围01-31

6.     int tm_mon;  //代表目前月份, 从一月算起, 范围从0-11

7.     int tm_year;  //从1900 年算起至今的年数

8.     int tm_wday;  //一星期的日数, 从星期一算起, 范围为0-6

9.     int tm_yday;  //从今年1 月1 日算起至今的天数, 范围为0-365

10.     int tm_isdst;  //日光节约时间的旗标

11. };

此函数返回的时间日期未经时区转换,而是UTC 时间。

返回值:返回结构tm 代表目前UTC 时间。

范例

1. #include <time.h>

2. main(){

3.     char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

4.     time_t timep;

5.     struct tm *p;

6.     time(&timep);

7.     p = gmtime(&timep);

8.     printf("%d%d%d", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday);

9.     printf("%s%d;%d;%d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);

10. }

执行结果:
2000/10/28 Sat 8:15:38

相关函数:time, ctime, gmtime, localtime

头文件:#include <time.h>

定义函数:char *asctime(const struct tm * timeptr);

函数说明:asctime()将参数timeptr 所指的tm 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为:"Wed Jun 30 21:49:08 1993\n"

返回值:若再调用相关的时间日期函数,此字符串可能会被破坏。此函数与ctime 不同处在于传入的参数是不同的结构。

附加说明:返回一字符串表示目前当地的时间日期.

范例

1. #include <time.h>

2. main(){

3.     time_t timep;

4.     time (&timep);

5.     printf("%s", asctime(gmtime(&timep)));

6. }

执行
Sat Oct 28 02:10:06 2000

相关函数:get_current_dir_name, getwd, chdir

clock_t定义

在time.h文件中,我们可以找到对它的定义:

#ifndef _CLOCK_T_DEFINED

typedef long clock_t;

#define _CLOCK_T_DEFINED

#endif

很明显,clock_t是一个长整形数。在time.h文件中,还定义了一个常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,其定义如下:

#define CLOCKS_PER_SEC ((clock_t)1000)

在linux系统下,CLOCKS_PER_SEC的值可能有所不同,目前使用的linux打印出来的值是1000000,表示的是微秒。这一点需要注意。

可以看到每过千分之一秒(1毫秒),调用clock()函数返回的值就加1。下面举个例子,你可以使用公式clock()/CLOCKS_PER_SEC来计算一个进程自身的运行时间:

void elapsed_time()

{

printf("Elapsed time:%u secs.\n",clock()/CLOCKS_PER_SEC);

}

当然,你也可以用clock函数来计算你的机器运行一个循环或者处理其它事件到底花了多少时间:

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

int main(void)

{

long i = 10000000L;

clock_t start, finish;

double duration;

/* 测量一个事件持续的时间*/

printf( "Time to do %ld empty loops is ", i) ;

start = clock();

while( i-- );

finish = clock();

duration = (double)(finish - start) / CLOCKS_PER_SEC;

printf( "%f seconds\n", duration );

system("pause");

}

运行结果

Time to do 10000000 empty loops is 0.03000 seconds

上面我们看到时钟计时单元的长度为1毫秒,那么计时的精度也为1毫秒,那么我们可不可以通过改变CLOCKS_PER_SEC的定义,通过把它定义的大一些,从而使计时精度更高呢?通过尝试,你会发现这样是不行的。在标准C/C++中,最小的计时单位是一毫秒。

getcwd()函数
头文件:#include <unistd.h>

定义函数:char * getcwd(char * buf, size_t size);

函数说明:getcwd()会将当前的工作目录绝对路径复制到参数buf 所指的内存空间,参数size 为buf 的空间大小。

注:
1、在调用此函数时,buf 所指的内存空间要足够大。若工作目录绝对路径的字符串长度超过参数size 大小,则返回NULL,errno 的值则为ERANGE。
2、倘若参数buf 为NULL,getcwd()会依参数size 的大小自动配置内存(使用malloc()),如果参数size 也为0,则getcwd()会依工作目录绝对路径的字符串程度来决定所配置的内存大小,进程可以在使用完次字符串后利用free()来释放此空间。

返回值:执行成功则将结果复制到参数buf 所指的内存空间, 或是返回自动配置的字符串指针. 失败返回NULL,错误代码存于errno.

范例
#include <unistd.h>
main()
{
    char buf[80];
    getcwd(buf, sizeof(buf));
    printf("current working directory : %s\n", buf);
}

执行:
current working directory :/tmp

Mkdir()函数

mkdir的函数原型(使用时需包含#include <sys/stat.h>):

int mkdir(const char *path, mode_t mode);

参数:

path——目录名,比如abc,/var/www/abc等

mode——目录权限

返回值:

返回0 表示成功, 返回 -1表示错误,并且会设置errno值。

关于Mode定义,请参考:http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysstat.h.html

当然你也可以不用那些类似S_IRWXU、S_IRUSR...类似的宏参数,毕竟很难记忆,反倒不如8进制的0421好记。组合样式为:owner-group-others,不同人都分三个规则读-写-执行(r-w-x),全部许可就是7。

1、编程时使用mkdir("test",777)报错 
试一下:

mkdir("test",0777);

写成mkdir("test",777)有可能无法执行。但是依稀记得,以前都是用777的也没错误,具体忘记了,反正按照规范写绝对没错。

2、umask命令使用 
另外假设你的程序目录在/root/abc/下,那么如果你的程序执行时想在/var/www下创建目录时,有可能你始终创建一个0777的目录总是创建成0755目录,这时可以尝试使用umask(0)命令。

umask只对当前目录有效,默认umask值为0022,所以你无法在另外一个地方直接创建0777的目录。

而是0777-0022=0755

3、如何创建某个用户组的文件夹 
/etc/passwd和/etc/group找到UID和gid

mkdir /var/ugroup

我们可以直接使用chown来改变文件所有者。

chown root:newuser /var/ugroup

修改权限

chmod 740 /var/ugroup/*

4、察看创建后目录权限情况命令: 
定位到该用户组目录下,执行:

ls -all

会显示类似:

drwxrwxr-x

这样的结果(0775)。

头文件:#include <stdio.h>

remove()函数用于删除指定的文件,其原型如下:
    int remove(char * filename);

【参数】filename为要删除的文件名,可以为一目录。如果参数filename 为一文件,则调用unlink()处理;若参数filename 为一目录,则调用rmdir()来处理。

【返回值】成功则返回0,失败则返回-1,错误原因存于errno。

错误代码:

1. EROFS  欲写入的文件为只读文件。

2. EFAULT  参数filename 指针超出可存取内存空间。

3. ENAMETOOLONG  参数filename 太长。

4. ENOMEM  核心内存不足。

5. ELOOP  参数filename 有过多符号连接问题。

6. EIO I/O  存取错误。

【实例】下面的程序演示了如何使用remove()函数删除文件。

1. #include<stdio.h>

2. int main(){

3.     char filename[80];

4.     printf("The file to delete:");

5.     gets(filename);

6.     if( remove(filename) == 0 )

7.         printf("Removed %s.", filename);

8.     else

9.         perror("remove");

10. }

运行上述程序,首先声明用于保存文件名的字符数组变量,从控制台获取文件名,然后删除该文件,并根据删除结果输出相应的提示信息。

Linux c中一些常用函数总结(c语言中文网。。。)相关推荐

  1. Linux Shell中的延时函数

    Linux Shell中的延时函数 在 linux shell 脚本中经常需要做一些延时处理. 所以经常要用到 sleep 或 usleep 函数. 下面来说一下  sleep 和 usleep 的区 ...

  2. linux启动程序api编程,Linux编程中关于API函数与系统调用间关系

    用户态xyz()函数,内核最终一般会调用形如sys_xyz()的服务例程来处理(不过也有一些例外,这里暂时不考虑) 函数xyz()是直接提供给用户编程使用的.图中"SYSCALL" ...

  3. Linux 编程中的API函数和系统调用的关系【转】

    转自:http://blog.chinaunix.net/uid-25968088-id-3426027.html 原文地址:Linux 编程中的API函数和系统调用的关系 作者:up哥小号 API: ...

  4. Python之pandas:pandas中数据处理常用函数(与空值相关/去重和替代)简介、具体案例、使用方法之详细攻略

    Python之pandas:pandas中数据处理常用函数(与空值相关/去重和替代)简介.具体案例.使用方法之详细攻略 目录 pandas中数据处理常用函数(isnull/dropna/fillna/ ...

  5. Linux系统常用函数,浅谈linux下的一些常用函数的总结(必看篇)

    1.exit()函数 exit(int n)  其实就是直接退出程序, 因为默认的标准程序入口为int main(int argc, char** argv),返回值是int型的. 一般在shell下 ...

  6. c语言中math的库函数,C语言中math.h库中的常用函数

    C语言中math.h库中的常用函数 int abs(int i) 返回整型参数i的绝对值 double cabs(struct complex znum) 返回复数znum的绝对值 double fa ...

  7. php spl函数,PHP SPL标准库中的常用函数介绍

    这篇文章主要介绍了PHP SPL标准库中的常用函数介绍,本文着重讲解了spl_autoload_extensions().spl_autoload_register().spl_autoload()三 ...

  8. json pandas 内存溢出_pandas中的常用函数

    Pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具. 近年随着大数据时代的到来,产生 ...

  9. [C++基础]队列queue中的常用函数

    [C++基础]队列queue中的常用函数 本博客转载自:https://www.cnblogs.com/xuning/p/3321733.html 在C++中只要#include即可使用队列类,其中在 ...

  10. linux probe函数调用,【整理】Linux驱动中,probe函数何时被调用

    [整理]Linux驱动中,probe函数何时被调用 用SourceInsight跟踪: 从driver_register看起,此处我的这里是: int driver_register(struct d ...

最新文章

  1. 图解VC++开发ActiveX控件C#调用
  2. ibatis插入正确但查询不出数据的问题
  3. 概率论-3.4 多维随机变量的特征数
  4. [C/C++面试题]-错题笔记与解析
  5. jquery 赋值时不触发change事件解决
  6. 程序员过关斩将--你的面向接口编程一定对吗?
  7. 企业实战02:Oracle数据库的安装和卸载
  8. HoughLine变换
  9. 深度对比Apache CarbonData、Hudi和Open Delta三大开源数据湖方案
  10. 华为云NP考试题库_阿里云ACP大数据及云计算经验感悟
  11. 如果理解Javascript利用闭包循环绑定事件
  12. [Linux] Ubuntu Server 12.04 LTS 平台上搭建WordPress(Nginx+MySQL+PHP) Part IV
  13. laravel 5 : Class 'input' not found
  14. asp.net执行js出现“已终止操作”的解决方法
  15. GPU机器无法使用GPU
  16. 信号与系统 实验三 傅里叶变换、系统的频域分析
  17. 阿泰,水晶报表--掌控对象
  18. fiddler抓包指南(浏览器、app抓包及证书安装)
  19. 如何避免动态字体Font Texture过大
  20. 我的世界java版怎么输入不了汉字_我的世界中国版文字消失的6种解决办法

热门文章

  1. 怎样提高java平台的性能
  2. Oracle EBS-SQL (PO-10):检查过期采购未接收订单.sql
  3. 在Windows Server 2008下安装Oracle 10g出现未知错误
  4. 附上一张公司项目解决方案的工程图
  5. WM 仓库管理T-CODE
  6. 用qt调用第三方库resolve
  7. VideoView播放视频会引起其它音乐播放器暂停问题解决
  8. mysql双主配置及其注意事项
  9. 程序员面试题100题第14题-圆圈中最后剩下的数字
  10. Sun发布MySQL 5.4 响应速度提升90% ?