文件操作函数总结(Linux)

 

目录

 一、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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/332142.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一款开源且不限制大小可以设置过期时间的支持分享的的开源文件共享系统picoshare 部署教程

1.拉取镜像 2.部署 创建目录 mkdir -p /opt/picoshare/data 部署 其中:"somesecretpass"是密码 docker run \--env "PORT4001" \--env "PS_SHARED_SECRETsomesecretpass" \--publish 10005:4001/tcp \--volume "/opt/picoshare/data:…

UG阵列-数字递增

在UG中&#xff0c;我们对一个文本进行阵列&#xff0c;可以得到很多个相同文本&#xff0c;但是如果文本中的数据是递增数列&#xff0c;需要用到表达式 先画一根参考线&#xff0c;标注参考线长度&#xff0c;并记录系统生成对应长度的表达式&#xff0c;例如p15 然后插入一个…

IO、NIO、IO多路复用

IO是什么&#xff1f; IO分为两类&#xff0c;它们之间是有区别的&#xff0c;而且有很大的区别&#xff1b;1. 文件系统的IO 也叫本地io&#xff0c;就是和磁盘或者外围存储设备进行读写操作&#xff0c;外围设备有USB、移动硬盘等等&#xff1b;2. 网络的IO 将数据发送给对方…

Android12 授予APK默认权限

不同于以往的Android版本 可以直接在此处设置: Android/frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java private void grantDefaultSystemHandlerPermissions(PackageManagerWrapper pm, int userId) {Log.i(TAG, &q…

flutter 环境搭建异常记录

flutter 环境搭建异常记录 1.执行flutter doctor自检报错 排查Android studio里配置的sdk是哪个 SDK Platforms选中 8.0 SDkTools也只勾选8.0 2.bash_profile 文件配置 没有的话 在根目录新建 export PUB_HOSTED_URLhttps://pub.flutter-io.cn export FLUTTER_STORAGE_…

【Npm】一文了解透彻package.json里的script字段以及相关知识

本文会从介绍npm run的原理、script字段作用、node_modules/.bin文件夹是什么 一、什么是npm script 在package.json里面定义的scripts字段就是&#xff0c;它的每一个属性都对于一段脚本。 {// ..."scripts": {"build": "node build.js"} }其…

6.3.5编辑视频

6.3.5编辑视频 除了上面的功能外&#xff0c;Camtasia4还能进行简单的视频编辑工作&#xff0c;如媒体的剪辑、连接、画中画等。 下面我们就利用Camtasia4的强大功能来实现一个画中画效果&#xff0c;在具体操作之前&#xff0c;需要准备好两个视频文件&#xff0c;一个作为主…

docker:Java通过nginx获取客户端的真实ip地址

问题现象 我们的平台使用Spring Cloud微服务架构&#xff0c;使用Spring Boot构建Java服务&#xff0c;使用google的jib插件打成docker镜像包我们使用docker虚拟化部署&#xff0c;使用docker-compose统一管理所有服务&#xff0c;包括Java服务和nginx等组件我们前后端分离&am…

蓝天采集器,功能逆天的网站数据抓取神器,轻松助你成为采集达人,附带搭建配置文档

源码介绍 蓝天采集器是一款专为web服务器打造的数据采集神器。与市面上常见的桌面端采集工具&#xff08;如火车头等&#xff09;相比&#xff0c;蓝天采集器在易用性、上手成本和灵活性方面更胜一筹。它部署简便&#xff0c;无需复杂的设置&#xff0c;即可迅速融入您的web服…

路由器初始化配置、功能配置

实验环境 拓扑图 Ip规划表&#xff08;各组使用自己的IP规划表&#xff09; 部门 主机数量 网络地址 子网掩码 网关 可用ip Vlan 市场部 38 192.168.131.0 255.255.255.0 192.168.131.1 2-254 11 研发部 53 192.168.132.0 255.255.255.0 192.168.132.1 2-2…

浅析CXL P2P DMA加速数据传输拥堵问题的解决方案

接上文&#xff1a;CXL P2P DMA加速数据传输的拥堵问题 为了改善这个问题&#xff0c;CXL 3.0引入了Unordered-IO和Back Invalidate Snoop新机制&#xff0c;允许更直接和高效点对点数据传输&#xff0c;以减轻上游CXL通道的压力并减少延迟。 (1)Unordered-IO (UIO) 在传统PCI…

Java如何做到无感知刷新token含示例代码(值得珍藏)

1. 前言 在系统页面进行业务操作时&#xff0c;有时会突然遇到应用闪退&#xff0c;并被重定向至登录页面&#xff0c;要求重新登录。此问题的出现&#xff0c;通常与系统中用于存储用户ID和token信息的Redis缓存有关。具体来说&#xff0c;这可能是由于token过期所导致的身份…

shell编程-3

文章目录 shell学习第三天while 循环第一天的小游戏练习: 编写抽同学回答问题的脚本要想让这个脚本永久有效如何知道两个文件里的内存一样&#xff1f;如何判断某个人已经抽过了 文本处理相关命令seqxargsuniqsorttrcutawkpastesplitcoljoin小结一下作业 小知识点写脚本的流程怎…

【蓝桥杯EDA设计与开发】资料汇总以及立创EDA及PCB相关技术资料汇总(持续更新)

[18/01/2024]&#xff1a;目前为了准备蓝桥杯做一些资料贴&#xff0c;于是写下这一篇博客。 各种资料均来源于网络以及部分书籍、手册等文档&#xff0c;参考不保证其准确性。 如果在准备蓝桥杯&#xff0c;可与我私信共同学习&#xff01;&#xff01;&#xff01;&#xf…

【人工智能课程】计算机科学博士作业一

【人工智能课程】计算机科学博士作业一 1 任务要求 模型拟合&#xff1a;用深度神经网络拟合一个回归模型。从各种角度对其改进&#xff0c;评价指标为MSE。掌握技巧&#xff1a; 熟悉并掌握深度学习模型训练的基本技巧。提高PyTorch的使用熟练度。掌握改进深度学习的方法。 …

sc.pl.umap 画feature plot

今天有时间尝试测试了这个scanpy的feature plot,其实很简单&#xff0c;就是使用 sc.pl.umap(adata,color"gene name"), 但是这个地方就有一个问题&#xff0c;这个画出来的值是原始的基因值还是scale之后的&#xff0c;这个我得搞清楚 首先看使用例子&#xff0c;参…

Linux shell编程学习笔记40:stat命令

程序员必备的面试技巧 “程序员必备的面试技巧&#xff0c;就像是编写一段完美的代码一样重要。在面试战场上&#xff0c;我们需要像忍者一样灵活&#xff0c;像侦探一样聪明&#xff0c;还要像无敌铁金刚一样坚定。只有掌握了这些技巧&#xff0c;我们才能在面试的舞台上闪耀…

QT-贪吃小游戏

QT-贪吃小游戏 一、演示效果二、关键程序三、下载链接 一、演示效果 二、关键程序 #include "Snake.h" #include "Food.h" #include "Stone.h" #include "Mushroom.h" #include "Ai.h" #include "Game.h" #inclu…

[Linux 进程(五)] 程序地址空间深度剖析

文章目录 1、前言2、什么是进程地址空间&#xff1f;3、进程地址空间的划分4、虚拟地址与物理地址的关系5、页表的作用扩展 6、为什么要有地址空间&#xff1f; 1、前言 Linux学习路线比较线性&#xff0c;也比较长&#xff0c;因此一个完整的知识点学习就会分布在两篇文章中&…

zabbix客户端配置及自定义监控

部署zabbix客户机 1.服务端和客户端都配置时间同步 yum install -y ntpdate ntpdate -u ntp.aliyun.com 2.服务端和客户端都设置 hosts 解析 cat > /etc/hosts << EOF 172.16.23.16 localhost 172.16.23.17 zbx-server EOF 3.被监控端 //设置 zabbix 的下载源&…