文件操作函数总结(Linux)

发布时间:2024年01月18日

?

目录

?一、fopen/fclose

二、fgetc/getc/getchar

三、fputc/putc/putchar

四、fgets/gets

?五、fputs/puts

六、fread/fwrite

六、open/close

七、ftell/fssek/rewind/fflush

?八、sprintf/sscanf/fprintf/fscanf

九、opendir/closedir/readdir

十、stat

十一、动态/静态库?


?一、fopen/fclose

其中w和w+都会清空文件,且如果文件不存在会创建新的文件

而r和r+只有在文件存在的时候才能使用,只是一个是只读,一个可以读写,也好记,你都需要读取了,文件肯定必须存在。

而a和a+就比较高级,他们和w的区别就是不会截断,就是他不会清空原本的文件,且也会和w一样创建新文件,其中a只可以写,而a+为读写。
  1. fp = fopen("test0.txt", "w"); - 以写入模式打开文件。如果文件已经存在,其内容将被截断。如果文件不存在,则创建一个新文件。
  2. fp = fopen("test0.txt", "w+"); - 以读取和写入模式打开文件。如果文件已经存在,其内容将被截断。如果文件不存在,则创建一个新文件。

  3. fp = fopen("test0.txt", "r"); - 以读取模式打开文件。文件必须存在;否则,将返回NULL

  4. fp = fopen("test0.txt", "r+"); - 以读取和写入模式打开文件。文件必须存在;否则,将返回NULL

  5. fp = fopen("test0.txt", "a"); - 以在文件末尾写入模式打开文件。如果文件不存在,则创建一个新文件。

  6. fp = fopen("test0.txt", "a+"); - 以在文件末尾读取和写入模式打开文件。如果文件不存在,则创建一个新文件。

?示例代码:

#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<stdio.h>
int main(int argc,const char* argv[])
{
	FILE* fp;
	if(fp == NULL)
	{
        printf("%s\n",strerror(errno));
        exit(-1);
     }

//	fp = fopen("test0.txt","w");//只写
//	fp = fopen("test0.txt","w+");
	fp = fopen("test0.txt","r");
//	fp = fopen("test0.txt","r+");
//	fp = fopen("test0.txt","a");
//	fp = fopen("test0.txt","a+");
	
	fclose(fp);
	return 0;
}

????????当我以只读方式打开时,本来存在test0.txt文件,程序运行不会报错,但是当我删除该文件后,报错,如下所示:

二、fgetc/getc/getchar

int  fgetc(FILE *stream);
int  getc(FILE *stream);   //宏
int  getchar(void);
成功时返回读取的字符;若到文件末尾或出错时返回EOF(-1),
getchar()等同于fgetc(stdin)
getc和fgetc区别是一个是宏一个是函数

注意事项:
1函数返回值是int类型不是char类型,主要是为了扩展返回值的范围。
2 stdin也是FILE *的指针,是系统定义好的,指向的是标准输入(键盘输入)
3 打开文件后读取,是从文件开头开始读。读完一个后读写指针会后移。读写注意文件位置!
4 调用getchar会阻塞,等待你的键盘输入

?示例一:?每次只能获取一个字符

#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>

int main()
{
	FILE* fp;
	fp = fopen("test2.txt","a+");
	if(fp == NULL)
	{
		printf("%s\n",strerror(errno));
		exit(-1);
	}
	int ret = fgetc(fp);
	if(ret == EOF)
	{
		perror("fgetc");
		fclose(fp);
		fp = NULL;
		exit(-1);
	}
	printf("%c\n",ret);
	fclose(fp);
	fp = NULL;
	return 0;
}

三、fputc/putc/putchar

int  fputc(int c, FILE *stream);
int  putc(int c, FILE *stream);
int  putchar(int c);

成功时返回写入的字符;出错时返回EOF
putchar(c)等同于fputc(c, stdout)
注意事项:
1返回和输入参数都是int类型
2遇到这种错误:Bad file descriptor,  很可能是文件打开的模式错误(只读模式去写,只写模式去读)

示例代码: 打印26个大写字母到1.txt文本

运行结果为:ABCDEFGHIJKLMNOPQRSTUVWXYZ,其对应的ASCII码值为65-90。

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ vi fputc.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o fputc fputc.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./fputc
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ls
1.txt  fetc  fgetc  fgetc.c  fopen  fopen.c  fputc  fputc.c  test01  test02  test2.txt
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat 1.txt
ABCDEFGHIJKLMNOPQRSTUVWXYZzhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ 

?详细实现代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
	int ret = 0;
	FILE* fp;
	fp = fopen("1.txt","w");
	if(fp == NULL)
	{
		printf("%s\n",strerror(errno));
		exit(-1);
	}
	for(int ch =  65; ch <= 90; ch++ )
    {
        ret = fputc(ch, fp);
		if(ret == EOF)
     	 {
        	  perror("fputc");
        	  fclose(fp);
         	 exit(-1);
     	 } 
    }
	fclose(fp);
	fp = NULL;
	return 0;
}

注意fputc函数的第一个参数,是要被写入的字符,但是是以该字符对应的int值进行传递的,所以需要注意ascii表,不是所有都拥有ASCII码的。?

四、fgets/gets

char  *gets(char *s);  读取标准输入到缓冲区s
char *fgets(char *s, int size, FILE *stream);

成功时返回s,到文件末尾或出错时返回NULL
遇到’\n’或已输入size-1个字符时返回,总是包含’\0’

注意事项:
1 gets函数已经被淘汰,因为会导致缓冲区溢出
2 fgets 函数第二个参数,输入的数据超出size,size-1个字符会保存到缓冲区,最后添加’\0’,如果输入数据少于size-1 后面会添加换行符。

?打印1.txt里的所有字符:到文件末尾或出错时返回NULL

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ vim testtest.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o test testtest.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./test
1705568744
sadjakjfklsajf;lskaf;
sfhjkshfoihwe joijwe;f
fhnsjhfoiu ewhj flkmwe
fhjwenfoiewjfo
hfbuqwhueifohnwe
fjijewoifmwe'
sngfiuewngioejwoifjweiojfwef'fasgfewag
sahfhewqgjoie4jgewkjgoiewqngiengoijqwekgjioweqhgskdjfiwef
sahguweiqhfuiwhenfuwenuiwehfjwenf
gfuewhfiuwehfuhweuiqwheuwqheuiqwehuwqiehwqueihweuqihwuqiehqwuihqweuhqwiuhewquiw
shfshf
fhjas
d
fhuiwehfiuhoiw
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat  testtest.c
#include<stdio.h>
int main()
{
FILE* fp;
fp = fopen("1.txt","a+");
char buf[100] = {0};
while(fgets(buf,sizeof(buf)-1,fp) != NULL)
{
	printf("%s",buf);
}


fclose(fp);
return 0;
}
zhi

?打印文件里有几行:

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ vim testtest.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o test testtest.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./test
1
1705568744

2
sadjakjfklsajf;lskaf;

3
sfhjkshfoihwe joijwe;f

4
fhnsjhfoiu ewhj flkmwe

5
fhjwenfoiewjfo

6
hfbuqwhueifohnwe

7
fjijewoifmwe'

8
sngfiuewngioejwoifjweiojfwef'fasgfewag

9
sahfhewqgjoie4jgewkjgoiewqngiengoijqwekgjioweqhgskdjfiwef

10
sahguweiqhfuiwhenfuwenuiwehfjwenf

11
gfuewhfiuwehfuhweuiqwheuwqheuiqwehuwqiehwqueihweuqihwuqiehqwuihqweuhqwiuhewquiw

12
shfshf

13
fhjas

14
d

15
fhuiwehfiuhoiw

?示例代码:

成功时返回s,到文件末尾或出错时返回NULL
遇到’\n’或已输入size-1个字符时返回,总是包含’\0’

#include<stdio.h>
#include<string.h>
int main()
{
FILE* fp;
fp = fopen("1.txt","a+");
char buf[1000];
static int linecount = 0;
while(fgets(buf,sizeof(buf)-1,fp) != NULL)
{
          if(buf[strlen(buf)-1] == '\n')
		  {  //注意判断是否是一行结束
 				linecount++;
				
                printf("%d\n",linecount);
			    printf("%s\n",buf);
          }

}

fclose(fp);
return 0;
}

新建一个名为test.txt的文本文件,向文件内输入"This is test.\n"(""内是输入的内容)?

运行结果:

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o fgets fgets.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./fgets
This is test.\n
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat test.txt
This is test.\n
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ 

?示例代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    FILE *file = fopen("test.txt", "r+");
    if (file == NULL)
	{
        perror("Error opening file");
        exit(-1);
    }

    char buffer[100];
    while (fgets(buffer, sizeof(buffer)-1, file) != NULL) 
	{
        printf("%s", buffer);
    }

    fclose(file);
	file = NULL;
    return 0;
}

?五、fputs/puts

int  puts(const char *s);
int fputs(const char *s,  FILE *stream);

成功时返回非负整数;出错时返回EOF
puts将缓冲区s中的字符串输出到stdout,并追加’\n’
fputs将缓冲区s中的字符串输出到stream,不追加  ‘\n’

运行结果:?

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cp fgets.c fputs.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ls
1.txt  fetc  fgetc  fgetc.c  fgets  fgets.c  fopen  fopen.c  fputc  fputc.c  fputs.c  test01  test02  test2.txt  test.c  test.txt
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ vim fputs.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ls
1.txt  fetc  fgetc  fgetc.c  fgets  fgets.c  fopen  fopen.c  fputc  fputc.c  fputs.c  test01  test02  test2.txt  test.c  test.txt
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o fputs fputs.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./fputs
This is test.\n
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat test.txt
This is test.\n
hello,worldzhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ 

示例代码:

#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
    FILE *file = fopen("test.txt", "r+");
    if (file == NULL)
	{
        perror("Error opening file");
        exit(-1);
    }

    char buffer[100];
    while (fgets(buffer, sizeof(buffer)-1, file) != NULL) 
	{
        printf("%s", buffer);
    }
	int ret = 0;
	char array[100] = "hello,world";
	ret = fputs(array,file);
	if(ret == EOF)
	{
		perror("fputs");
		fclose(file);
		file = NULL;
		exit(-1);
	}
    fclose(file);
	file = NULL;
    return 0;
}

六、fread/fwrite

文本文件和二进制的区别:
存储的格式不同:文本文件只能存储文本。

计算机内码概念:文本符号在计算机内部的编码(计算机内部只能存储数字0101001....,所以所有符号都要编码)

二进制读写函数格式:
size_t fread(void *ptr, size_t size, size_t n, FILE *fp);
void *ptr  读取内容放的位置指针
  size_t size 读取的块大小
size_t n 读取的个数
  FILE *fp  读取的文件指针

size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);
void *ptr  写文件的内容的位置指针
size_t size 写的块大小
size_t n 写的个数
  FILE *fp  要写的文件指针

注意事项:
文件写完后,文件指针指向文件末尾,如果这时候读,读不出来内容。
解决办法:移动指针到文件头;关闭文件,重新打开
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ vim fread.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o fread fread.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat 2.txt
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./fread

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat 2.txt
hello,worldzhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ vim fread.c

可以看到这样的话,打印不出任何东西。

#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<stdio.h>
int main(int argc,const char* argv[])
{
	FILE* fp;
	if(fp == NULL)
	{
        printf("%s\n",strerror(errno));
        exit(-1);
     }

//	fp = fopen("test0.txt","w");//只写
	fp = fopen("2.txt","w+");
//	fp = fopen("2.txt","r");
//	fp = fopen("test0.txt","r+");
//	fp = fopen("test0.txt","a");
//	fp = fopen("test0.txt","a+");
	char array[100] = "hello,world";
	size_t result = fwrite(array,strlen(array),1,fp);
 	if (ferror(fp))
	{
        perror("Error write");
        fclose(fp);
        exit(-1);
    }
	char buffer[100];
	size_t ret = fread(buffer,10,1,fp);
	 if (ferror(fp))
	 {
        perror("fread");
        fclose(fp);
        exit(-1);
    }
	printf("%s\n",buffer);
	fclose(fp);
	return 0;
}

?修改如下:fseek(fp,0,SEEK_SET);

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ vim fread.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o fread fread.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./fread
hello,worl
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat fread.c
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<stdio.h>
int main(int argc,const char* argv[])
{
	FILE* fp;
	if(fp == NULL)
	{
        printf("%s\n",strerror(errno));
        exit(-1);
     }

//	fp = fopen("test0.txt","w");//只写
	fp = fopen("2.txt","w+");
//	fp = fopen("2.txt","r");
//	fp = fopen("test0.txt","r+");
//	fp = fopen("test0.txt","a");
//	fp = fopen("test0.txt","a+");
	char array[100] = "hello,world";
	size_t result = fwrite(array,strlen(array),1,fp);
 	if (ferror(fp))
	{
        perror("Error write");
        fclose(fp);
        exit(-1);
    }
	fseek(fp,0,SEEK_SET);
	char buffer[100];
	size_t ret = fread(buffer,10,1,fp);
	 if (ferror(fp))
	 {
        perror("fread");
        fclose(fp);
        exit(-1);
    }
	printf("%s\n",buffer);
	fclose(fp);
	return 0;
}

也可以采用先关闭再打开文件的方式,但是需要注意文件打开方式:我这里为了省事直接用的a+

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ vim fread.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o fread fread.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./fread
hello,worl
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat 2.txt
hello,worldzhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ 
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<stdio.h>
int main(int argc,const char* argv[])
{
	FILE* fp;
	if(fp == NULL)
	{
        printf("%s\n",strerror(errno));
        exit(-1);
     }

//	fp = fopen("test0.txt","w");//只写
//	fp = fopen("2.txt","w+");
//	fp = fopen("2.txt","r");
//	fp = fopen("test0.txt","r+");
	fp = fopen("2.txt","a+");
//	fp = fopen("test0.txt","a+");
	char array[100] = "hello,world";
	size_t result = fwrite(array,strlen(array),1,fp);
 	if (ferror(fp))
	{
        perror("Error write");
        fclose(fp);
        exit(-1);
    }
	fclose(fp);
	fopen("2.txt","a+");
//	fseek(fp,0,SEEK_SET);
	char buffer[100];
	size_t ret = fread(buffer,10,1,fp);
	 if (ferror(fp))
	 {
        perror("fread");
        fclose(fp);
        exit(-1);
    }
	printf("%s\n",buffer);
	fclose(fp);
	return 0;
}

六、open/close

?int close(int fd);

文件IO 打开
open
int open(const char *pathname, int flags);   不创建文件
int open(const char *pathname, int flags, mode_t mode);  创建文件,不能创建设备文件
成功时返回文件描述符;出错时返回EOF

文件IO和标准的模式对应关系:

r				O_RDONLY
r+				O_RDWR
w				O_WRONLY | O_CREAT | O_TRUNC, 0664
w+				O_RDWR | O_CREAT | O_TRUNC, 0664
a				O_WRONLY | O_CREAT | O_APPEND, 0664
a+				O_RDWR | O_CREAT | O_APPEND, 0664

umask概念:
umask 用来设定文件或目录的初始权限
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ umask
0002


文件的关闭
int close(int fd)
关闭后文件描述符不能代表文件

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat 1.txt
ABCDEFGHIJKLMNOPQRSTUVWXYZhello
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ rm -rf 1.txt
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./open
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ls
1.txt  fgetc    fgets.c  fputc    fputs.c  open    test02     test.c
2.txt  fgetc.c  fopen    fputc.c  fread    open.c  test0.txt  test.txt
fetc   fgets    fopen.c  fputs    fread.c  test01  test2.txt
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat 1.txt
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
int main()
{

	int fd = open("1.txt",O_RDWR|O_CREAT|O_APPEND,0666);
	if(fd == EOF)
	{
		perror("open");
		exit(-1);
	}
	
	close(fd);
	return 0;
}

七、ftell/fssek/rewind/fflush

fflush() 函数:
作用: 用于刷新流的缓冲区。当你写入或读取文件时,数据通常存储在缓冲区中,而不是立即写入或读取文件。fflush() 强制将缓冲区中的数据写入文件或清空输入缓冲区。

fseek() 函数:
作用: 用于定位文件流的位置。可以用它来移动文件指针到文件的指定位置,从而实现对文件的随机访问。
文件首SEEK_SET	当前位置SEEK_CUR  文件末尾SEEK_END	

rewind() 函数:
作用: 用于将文件指针重新定位到文件的开头。相当于调用 fseek(stream, 0, SEEK_SET)。

?fflush:

 int fflush(FILE *fp);

成功时返回0;出错时返回EOF
将流缓冲区中的数据写入实际的文件
Linux下只能刷新输出缓冲区,输入缓冲区丢弃

ftell/fssek/rewind:?

long ftell(FILE *stream);
long fseek(FILE *stream, long offset,  int whence);
void rewind(FILE *stream);
fseek 参数whence参数:SEEK_SET/SEEK_CUR/SEEK_END
SEEK_SET 从距文件开头 offset 位移量为新的读写位置
SEEK_CUR:以目前的读写位置往后增加 offset 个位移量
SEEK_END:将读写位置指向文件尾后再增加 offset 个位移量
offset参数:偏移量,可正可负

注意事项:
1.文件的打开使用a模式 fseek无效
2.rewind(fp) 相当于 fseek(fp,0,SEEK_SET);
3.这三个函数只适用2G以下的文件


zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc test_new.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./a.out
Current position: 13
position:0
Content: Hello, World!
Current position after fseek: 6
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ 

?第一次输出的位置是因为已经写入完成了,在文件末尾,输出13,指向!

第二次输出的位置为0,是因为使用了?rewind(file);其相当于 fseek(fp,0,SEEK_SET);

第三次输出位置为6,是因为使用了long fseek(FILE *stream, long offset, ?int whence);,其中offset设置为6,而whence设置为了SEEK_SET。

#include <stdio.h>

int main()
{
    FILE *file;
    char buffer[100];

    // 打开文件//读写
    file = fopen("example.txt", "w+");
	if(file == NULL)
	{
		perror("fopen");
	}
    // 写入一些数据到文件
    fprintf(file, "Hello, World!");
	
    // 获取文件位置指针的当前位置
    long position = ftell(file);
	if(position == EOF)
	{
		perror("ftell");
	}
    printf("Current position: %ld\n", position);

    // 设置文件位置指针到文件的开头
    rewind(file);
	position = ftell(file);
	printf("position:%ld\n",position);

	// 读取文件内容并打印
    fgets(buffer, sizeof(buffer), file);
    printf("Content: %s\n", buffer);

    // 设置文件位置指针到指定位置
    fseek(file, 6, SEEK_SET);

    // 获取文件位置指针的当前位置
    position = ftell(file);
    printf("Current position after fseek: %ld\n", position);

    // 关闭文件
    fclose(file);

    return 0;
}

?八、sprintf/sscanf/fprintf/fscanf

格式化输出
int fprintf(FILE *stream, const char *fmt, …);
int sprintf(char *s, const char *fmt, …);

成功时返回输出的字符个数;出错时返回EOF

格式化输入
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

??循环打印现在的时间:

#include<stdio.h>
#include<time.h>
int main()
{
    time_t ctime;
   struct tm*  current_time;
	while(1)
	{
		ctime = time(NULL);
		current_time = localtime(&ctime);
		printf("Current time: %04d-%02d-%02d\n",
		current_time->tm_year+1900,
		current_time->tm_mon+1,
		current_time->tm_mday);
	}
	return 0;
}

time()用来获取系统时间(秒数)
time_t time(time_t *seconds) 1970.1.1 0:0:0
localtime()将系统时间转换成本地时间
struct tm *localtime(const time_t *timer)
struct tm {
   int tm_sec;         /* 秒,范围从 0 到 59                */
   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;        /* 一年中的第几天,范围从 0 到 365                    */
   int tm_isdst;       /* 夏令时                        */    
};

注意:
   int tm_mon;        获取的值要加1是正确的月份
   int tm_year;        获取的值加1900是正确的年份

??使用fprintf和sprintf

?运行结果:

zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ gcc -o fprintf fprintf1.c
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ./fprintf
1705568744
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ ls
1.txt        fetc      fgetc.c  fopen.c     fputc    fread    test01     test.c
2.txt        fflush    fgets    fprintf     fputc.c  fread.c  test02     test_new.c
a.out        fflush.c  fgets.c  fprintf1.c  fputs    open     test0.txt  test.txt
example.txt  fgetc     fopen    fprintf.c   fputs.c  open.c   test2.txt
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ cat 1.txt
1705568744
zhibin@zhibin-virtual-machine:~/code_Learning/code_2024_1_18/lesson_csdn$ 

示例代码:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, const char* argv[])
{
    char buff[100] = {0};
    FILE* fp;
    fp = fopen("1.txt", "a+");
    if (fp == NULL) 
	{
        perror("fopen");
        exit(-1);
    }

    time_t ctime = time(NULL);

    sprintf(buff, "%ld", ctime);
    printf("%ld\n", ctime);
    fprintf(fp, "%ld\n", ctime);

    fclose(fp);
    return 0;
}

九、opendir/closedir/readdir

#include  <dirent.h>
 DIR  *opendir(const char *name);
 DIR *fdopendir(int fd);  使用文件描述符,要配合open函数使用
DIR是用来描述一个打开的目录文件的结构体类型
成功时返回目录流指针;出错时返回NULL
读取目录
#include  <dirent.h>
struct  dirent *readdir(DIR *dirp);
 
struct dirent是用来描述目录流中一个目录项的结构体类型
包含成员char  d_name[256]   参考帮助文档
成功时返回目录流dirp中下一个目录项;
出错或到末尾时时返回NULL
关闭目录
closedir函数用来关闭一个目录文件:
 #include  <dirent.h>
 int closedir(DIR *dirp);
 
成功时返回0;出错时返回EOF
struct dirent {
      ino_t          d_ino;       /* inode number 索引节点号*/
      off_t          d_off;       /* not an offset; see NOTES 在目录文件中的偏移*/
      unsigned short d_reclen;    /* length of this record 文件名长*/
      unsigned char  d_type;   /*type of file; not supported by all  filesystem types 文件类型*/              
                                                                                           
      char           d_name[256]; /* filename 文件名,最长255字符*/
};

??运行结果:

linux@linux:~/code_Linux/2024_1_15/test$ ./dir
test
..
.
lesson
linux@linux:~/code_Linux/2024_1_15/test$ ;s
bash: syntax error near unexpected token `;'
linux@linux:~/code_Linux/2024_1_15/test$ cd ..
linux@linux:~/code_Linux/2024_1_15$ ls
lesson  test
linux@linux:~/code_Linux/2024_1_15$ 

?示例代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<time.h>
#include<dirent.h>
int main(int argc,const char* argv[])
{
	DIR* dirp;
	struct dirent* dir;
	dirp = opendir("/home/linux/code_Linux/2024_1_15/");
	if(dirp == NULL)
	{
		perror("opendir");
		exit(-1);
	}
	while((dir = readdir(dirp)) != NULL)
	{
		printf("%s\n",dir->d_name);
	}
	closedir(dirp);
	dirp = NULL;
	return 0;
}

十、stat

#include  <sys/stat.h>
 int  stat(const char *path, struct stat *buf);
 int  lstat(const char *path, struct stat *buf);
 int  fstat(int fd, struct stat *buf);
  
成功时返回0;出错时返回EOF
如果path是符号链接stat获取的是目标文件的属性;而lstat获取的是链接文件的属性
struct dirent {
      ino_t          d_ino;       /* inode number 索引节点号*/
      off_t          d_off;       /* not an offset; see NOTES 在目录文件中的偏移*/
      unsigned short d_reclen;    /* length of this record 文件名长*/
      unsigned char  d_type;   /*type of file; not supported by all  filesystem types 文件类型*/              
                                                                                           
      char           d_name[256]; /* filename 文件名,最长255字符*/
};
S_ISREG(m) 是常规文件吗?
S_ISDIR (m) 目录吗?
S_ISCHR (m) 字符设备?
S_ISBLK (m) 块设备?
S_ISFIFO(m)  FIFO(命名管道)?
S_ISLNK (m) 符号链接呢? (不是posix . 1的授权- 1996)。
S_ISSOCK (m) 套接字? (不是posix . 1的授权- 1996)。
struct stat {

        mode_t     st_mode;       //文件对应的模式,文件,目录等
        ino_t      st_ino;       //inode节点号
        dev_t      st_dev;        //设备号码
        dev_t      st_rdev;       //特殊设备号码
        nlink_t    st_nlink;      //文件的连接数
        uid_t      st_uid;        //文件所有者
        gid_t      st_gid;        //文件所有者对应的组
        off_t      st_size;       //普通文件,对应的文件字节数
        time_t     st_atime;      //文件最后被访问的时间
        time_t     st_mtime;      //文件内容最后被修改的时间
        time_t     st_ctime;      //文件状态改变时间
        blksize_t st_blksize;    //文件内容对应的块大小
        blkcnt_t   st_blocks;     //伟建内容对应的块数量
      };

?这样始终打印的都是test.c的大小。

#include<stdio.h>
#include<stdlib.h>
#include<dirent.h>
#include<time.h>
#include<sys/stat.h>

int main()
{
	DIR* dirp;
	dirp = opendir("/home/linux/code_Linux/");
	if(dirp  == NULL)
	{
		perror("open");
		exit(-1);
	}
	struct dirent* dir;
	struct stat* buf;
	while((dir = readdir(dirp)) != NULL)
	{
		//遍历所有文件
		printf("%s:",dir->d_name);
		//打印大小
		stat("test.c",buf);
		printf(" %02d",(int)buf->st_size);
		printf("\n");
	}
	closedir(dirp);
	dirp = NULL;

	return 0;
}

?遍历一个文件夹下所有文件,并打印文件大小和日期:

?

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<dirent.h>
#include<time.h>
#include<sys/stat.h>

int main(int argc,const char* argv[])
{
	DIR* dir;
	dir = opendir("/home/zhibin/code_Learning/code_2024_1_17/lesson03");
	if(dir == NULL)
	{
		//打开失败
		perror("opendir");
		exit(-1);
	}
	//打开lesson03下的目录
	//遍历目录下的条目
	//使用readdir函数
	struct dirent* readret;
	struct stat buf;
	int ret = 0;
	while(NULL != (readret = readdir(dir)))
	{
			printf("%s:",readret->d_name);
			//打印时间和大小
			char file_path[256];
snprintf(file_path, sizeof(file_path), "%s/%s",
         "/home/zhibin/code_Learning/code_2024_1_17/lesson03", readret->d_name);

			//拼接出正确路径
			ret = stat(file_path,&buf);
			if(ret == EOF)
			{
				perror("stat");
				closedir(dir);
				exit(-1);
			}
		    printf(" %d", (int)buf.st_size);
			struct tm* last;
 		    last = localtime(&buf.st_ctime);
 		    printf(" %d-%d-%d %d:%d", last->tm_year + 1900,
 	        last->tm_mon + 1, last->tm_mday, last->tm_hour, last->tm_min);
			printf("\n");
		
	}

	return 0;
}

十一、动态/静态库?

静态库

创建静态库步骤:
1 . 编写库文件代码,编译为.o 目标文件。
2. ar 命令 创建  libxxxx.a 文件
   ar -rsv  libxxxx.a  xxxx.o
   注意:1 静态库名字要以lib开头,后缀名为.a
2 没有main函数的.c 文件不能生成可执行文件。


链接错误:
test.c:(.text+0x15):对‘hello’未定义的引用
collect2: error: ld returned 1 exit status
含义:表示hello函数在编译的源码内没有找到实现
解决:实现代码或者找到对应函数的库并且链接它。

链接静态库:

gcc -o 目标文件 源码.c  -L路径  -lxxxx

-L  表示库所在的路径
-l 后面跟库的名称


动态库的生成步骤:

1. 生成位置无关代码的目标文件
 gcc  -c  -fPIC  xxx.c xxxx.c ....
2. 生成动态库
   gcc  -shared -o libxxxx.so  xxx.o  xxx.o ....

3. 编译可执行文件
gcc -o 目标文件 源码.c  -L路径  -lxxxx
执行动态库的可执行文件错误
./test: error while loading shared libraries: libmyheby.so: cannot open shared object file: No such file or directory

含义:可执行文件所使用的动态库找不到
解决办法:
找到动态库,添加到/usr/lib里面
或者使用export  LD_LIBRARY_PATH=$LD_LIBRARY_PATH:你的动态库目录
添加在~/.bashrc 文件里面
使用source ~/.bashrc 生效。

查看可执行文件使用的动态库:
ldd 命令 :   ldd 你的可执行文件
root@haas-virtual-machine:/mnt/hgfs/share/newIOP# ldd test
	linux-vdso.so.1 =>  (0x00007fff6548d000)
	libmyheby.so => /mnt/hgfs/share/newIOP/day5/libmyheby.so (0x00007f5c89521000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5c89144000)
	/lib64/ld-linux-x86-64.so.2 (0x000055fe52211000)

root@haas-virtual-machine:/mnt/hgfs/share/newIOP/day5# ldd test
	linux-vdso.so.1 =>  (0x00007ffcb652c000)
	libmyheby.so => not found
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fbeeffaf000)
	/lib64/ld-linux-x86-64.so.2 (0x0000561003c3b000)

文章来源:https://blog.csdn.net/weixin_57604904/article/details/135653503
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。