Linux基础IO

C语言文件io

C语言打开文件

打开/关闭文件函数fopen/fclose:

FILE * fopen(const char* filename, const char* mode);
int fclose (FILE* stream );

文件打开方式:
文件打开方式

C语言库函数

fputc/fgetc函数

int fputc( int c,//字符(或者对应ASCII码值)
 FILE *stream //文件指针(或者流)
);
//https://www.runoob.com/cprogramming/c-function-fputc.html
int fgetc( FILE *stream );
//https://www.runoob.com/cprogramming/c-function-fgetc.html

C 库函数 int fputc(int char, FILE *stream) 把参数 char 指定的字符(一个无符号字符)写入到指定的流 stream 中,并把位置标识符往前移动。
https://www.runoob.com/cprogramming/c-function-fputc.html

C 库函数 int fgetc(FILE *stream) 从指定的流 stream 获取下一个字符(一个无符号字符),并把位置标识符往前移动。
https://www.runoob.com/cprogramming/c-function-fgetc.html

每当函数运行一次后,流(标准输入流或者文件流)的指针就会指向读取内容后一个空间的首地址
fpunc示例:

#include <stdio.h>
 
int main ()
{
   FILE *fp;
   int ch;
 
   fp = fopen("file.txt", "w+");
   for( ch = 33 ; ch <= 100; ch++ )
   {
      fputc(ch, fp);
   }
   fclose(fp);
 
   return(0);
}

fgetc示例:

#include <stdio.h>

int main ()
{
   FILE *fp;
   int c;
   int n = 0;
  
   fp = fopen("file.txt","r");
   if(fp == NULL) 
   {
      perror("打开文件时发生错误");
      return(-1);
   }
   do
   {
      c = fgetc(fp);
      if( feof(fp) )
      {
          break ;
      }
      printf("%c", c);
   }while(1);

   fclose(fp);
   return(0);
}

fputs/fgets函数

char *fgets( char *string, int n, FILE *stream );
 //https://www.runoob.com/cprogramming/c-function-fgets.html
int fputs( const char *string, FILE *stream );
//https://www.runoob.com/cprogramming/c-function-fputs.html

C 库函数 char *fgets(char *str, int n, FILE *stream) 从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。

C 库函数 int fputs(const char *str, FILE *stream) 把字符串写入到指定的流 stream 中,但不包括空字符。
fgets示例:

#include <stdio.h>

int main()
{
   FILE *fp;
   char str[60];

   /* 打开用于读取的文件 */
   fp = fopen("file.txt" , "r");
   if(fp == NULL) {
      perror("打开文件时发生错误");
      return(-1);
   }
   if( fgets (str, 60, fp)!=NULL ) {
      /* 向标准输出 stdout 写入内容 */
      puts(str);
   }
   fclose(fp);
   
   return(0);
}

fputs示例:

#include <stdio.h>

int main ()
{
   FILE *fp;

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

   fputs("这是 C 语言。", fp);
   fputs("这是一种系统程序设计语言。", fp);

   fclose(fp);
   
   return(0);
}

fscanf/fprintf-格式化读写函数

int fscanf( FILE *stream, const char *format [, argument ]... );
//https://www.runoob.com/cprogramming/c-function-fscanf.html

int fprintf( FILE *stream, const char *format [, argument ]...);
//https://www.runoob.com/cprogramming/c-function-fprintf.html

fscanf示例:

下面的实例演示了 fscanf() 函数的用法。

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


int main()
{
   char str1[10], str2[10], str3[10];
   int year;
   FILE * fp;

   fp = fopen ("file.txt", "w+");
   fputs("We are in 2014", fp);
   
   rewind(fp);
   fscanf(fp, "%s %s %s %d", str1, str2, str3, &year);
   
   printf("Read String1 |%s|\n", str1 );
   printf("Read String2 |%s|\n", str2 );
   printf("Read String3 |%s|\n", str3 );
   printf("Read Integer |%d|\n", year );

   fclose(fp);
   
   return(0);
}

让我们编译并运行上面的程序,这将产生以下结果:

Read String1 |We|
Read String2 |are|
Read String3 |in|
Read Integer |2014|

fprintf示例:

下面的实例演示了 fprintf() 函数的用法。

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

int main()
{
   FILE * fp;

   fp = fopen ("file.txt", "w+");
   fprintf(fp, "%s %s %s %d", "We", "are", "in", 2014);
   
   fclose(fp);
   
   return(0);
}

让我们编译并运行上面的程序,这将创建文件 file.txt,它的内容如下:

We are in 2014

sscanf/sprintf函数

int sprintf( char *buffer, const char *format [, argument] ... );
//https://www.runoob.com/cprogramming/c-function-sprintf.html

int sscanf( const char *buffer, const char *format [, argument ] ... );
//https://www.runoob.com/cprogramming/c-function-sscanf.html

sscanf示例:
下面的实例演示了 sprintf() 函数的用法。

#include <stdio.h>
#include <math.h>

int main()
{
   char str[80];

   sprintf(str, "Pi 的值 = %f", M_PI);
   puts(str);
   
   return(0);
}

让我们编译并运行上面的程序,这将产生以下结果:

Pi 的值 = 3.141593

scanf/printf、fscanf/fprintf、sscanf/sprintf函数对比

函数对比
scanf/printf格式化的I/O函数,针对的是标准输入流和输出流
fscanf/fprintf格式化的I/O函数,针对的是所有输入流和输出流
sscanf/sprintf在字符串中提取可格式化的数据输入,把格式化的数据转化为字符串输出

stdin/stdout/stderr

extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;

任何C程序运行都会默认打开三个输入输出流,分别是:stdin, stdout, stderr

分三个文件流分别对应键盘文件,显示器文件,显示器文件

实际上几乎所有的语言都会打开这三个文件

系统文件io

open接口

#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: 打开文件时,可以传入多个参数选项,用下面的一个或者多个常量进行“或”运算,构成flags

mode_t:如果没有对应文件需要进行创建的话,就需要指定创建文件的八进制访问权限值

参数选项含义
O_RDONLY以只读的方式打开文件
O_WRNOLY以只写的方式打开文件
O_APPEND以追加的方式打开文件
O_RDWR以读写的方式打开文件
O_CREAT当目标文件不存在时,创建文件

这里的参数选项是依靠不同的比特位来标识对应的功能设定,所以这里的异或操作就是将对应比特位置为1,同时函数也是通过对每个比特位进行与操作检查是否该比特位置为了1

#define O_RDONLY         00
#define O_WRONLY         01
#define O_RDWR           02
#define O_CREAT        0100

示例:

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<assert.h>

int main()
{
    FILE* fp=fopen("bite","w+");
    if(fp==NULL)
    {
        perror("fopen");
    }
    const char *ptr="linux so easy!";
    fwrite(ptr,strlen(ptr)+1,1,fp);
    char buffer[64];
    fseek(fp,0,SEEK_SET);
    fread(buffer,strlen(ptr),1,fp);
    printf("buffer:%s\n",buffer);
    return 0;
}

int main()
{
    int fd=open("bite",O_RDWR | O_CREAT | O_TRUNC, 0666);
    if(fd<0)
    {
        perror("open");
        return 1;
    }
    const char* ptr="i like linux";    
    write(fd,ptr,strlen(ptr));
    lseek(fd,0,SEEK_SET);
    char buffer[64];
    read(fd,buffer,32);
    printf("buffer:%s\n",buffer);
    close(fd);
    return 0;
}

文件描述符

0 & 1 & 2

Linux进程默认情况下会有3个缺省打开的文件描述符,分别是标准输入0, 标准输出1, 标准错误2.
0,1,2对应的物理设备一般是:键盘,显示器,显示器
所以输入输出还可以采用如下方式:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>

int main()
{
	char buf[1024];
	ssize_t s = read(0, buf, sizeof(buf));
	if(s > 0)
	{
		buf[s] = 0;
		write(1, buf, strlen(buf));
		write(2, buf, strlen(buf));
	}
	return 0;
}

在这里插入图片描述

文件描述符的分配规则

在files_struct数组当中,找到当前没有被使用的最小的一个下标,作为新的文件描述符

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
	int fd = open("myfile", O_RDONLY);
	if(fd < 0)
	{
		perror("open");
		return 1;
	}
	printf("fd: %d\n", fd);
	close(fd);
	return 0;
}
输出:fd: 3
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
	close(0);
	//close(2);
	int fd = open("myfile", O_RDONLY);
	if(fd < 0)
	{
		perror("open");
		return 1;
	}
	printf("fd: %d\n", fd);
	close(fd);
	return 0;
}
输出: fd: 0 或者 fd 2 

重定向

重定向输出

在 Linux 系统中,使用 > 字符表示重定向输出。例如,将 ls 命令的输出重定向到一个文件中:

$ ls > list.txt

执行此命令不会在显示器上输出信息而是将信息重定向至list.txt
我们也可以使用c语言进行重定向:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
	close(1);
	int fd = open("myfile", O_WRONLY|O_CREAT, 00644);
	if(fd < 0)
	{
		perror("open");
		return 1;
	}
	printf("fd: %d\n", fd);
	fflush(stdout);
	close(fd);
	exit(0);
}

和使用bash的效果是一样的
从上述示例来看,输出重定向是将进程中的文件指针数组中的标准输出stdout文件给关闭(并非真正关闭,而是将指针数组对应下标的内容置空),再将新打开文件分配到标准输出文件对应的下标上,再输出时,系统不知道文件已经替换,依旧输出到stdout文件对应的数组下标为1的文件上,但是此时文件已经被替换了

dup2

#include <unistd.h>
int dup2(int oldfd, int newfd);//将文件地址oldfd替换到newfd上

其中newfd是被oldfd替代的

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


int main()
{
    umask(0);
    int fd = open("log.txt", O_RDONLY);
    if(fd < 0)
    {
        perror("open");
        return 1;
    }

    dup2(fd, 0); //输入重定向

    char line[64];

    while(1)
    {
        printf("> "); 
        if(fgets(line, sizeof(line), stdin) == NULL) break; //stdin->0
        printf("%s", line);
    }
    close(fd);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值