第六章 Linux 标准 I/O 概述

初步了解I/O以及相关的API函数想把每个问题都细究,发现什么都解决不了。关于此部分,我先了解相关概念,懂得输入输出在linux操作系统是如何运作,以及如何调用相关的I/O函数即可,更为深入的以后在项目中碰到再说。

1、什么是标准 I/O

标准 I/O 指的是 ANSIC 中定义的用于 I/O 操作的一系列函数
只要操作系统中安装了 C 库,标准 I/O 函数就可以调用。换句话说,如果程序中使用的是标准 I/O 函数,那么源代码不需要修改就可以在其他操作系统下编译运行,具有更好的可移植性。

2、I/O干什么用的(输入输出用的)
IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。

2、什么是标准 I/O下一个重要概念——流的含义

标准 I/O 的核心对象就是流。当用标准 I/O 打开一个文件时,就会创建一个 FILE 结构体描述该文件( 或者理解为创建一个 FILE 结构体和实际打开的文件关联起来)。我们把这个FILE 结构体形象地称为流。标准 I/O 函数都基于流进行各种操作

4、流的相关函数

a、fopen();//流的开启

(b)fclose();//流的关闭

 程序结束时会自动关闭所有打开的流。

(c)perror();错误处理:标准 I/O函数执行时如果出现错误,会把错误码保存在全局变量 errno中。程序员可以通过相应的函数打印错误信息。

 代码解析

如果文件 1.txt 不存在,程序执行时会打印 fopen: No such file or directory
#include <stdio.h>
int main(int argc, const char *argv[])
{
        FILE *fp; // 定义流指针
        if ((fp = fopen("1.txt", "r")) == NULL) // fopen失败返回NULL
        {
                perror("fopen"); // 输出错误信息
                return -1;
        }
        fclose(fp);//关闭流
        return 0;
}

(d)strerror()函数语法要点:

 (e)按字符(字节)输入

int getc(FILE * stream);
int fgetc(FILE * stream);
int getchar(void);

getc()和fgetc ()从指定的流中读取一个字符(节), getchar()从stdin中读取一个字符(节)。
 

(f)字符输出函数

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

putc()和 fputc()向指定的流输出一个字符(节), putchar()函数向 stdout 输出一个字符(节)。

编写fput.c文件

#include <stdio.h>
int main(int argc, const char *argv[])
{
        int c;
        while (1)
        {
                c = fgetc(stdin); // 从键盘读取一个字符
                if ((c >= '0') && (c <= '9')) fputc(c, stdout); // 若输入的是数字,输出
                if (c == '\n') break; // 若遇到换行符,跳出循环
        }
        return 0;
}

//stdin、stdout是什么?暂时不知。

运行结果如下。
linux@ubuntu:~$ ./fput
hello12345world
123452.

(g)按行输入

如果文件 1.txt 不存在,程序执行时会打

char * gets(char *s)
char * fgets(char * s, int size, FILE * stream)

s:存放输入字符串的缓冲区首地址

size:输入的字符串长度

stream:对应的流

gets 函数容易造成缓冲区溢出,不推荐大家使用。
fgets 从指定的流中读取一个字符串,当遇到\n 时,会读取\n 或读取 size-1 个字符后返回。
注意: fgets 不能保证每次都能读出一行。
 

(h) 行输出函数

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

s:存放输出字符串的缓冲区首地址

stream:对应的流

下面以 fgets()为例计算一个文本文件的行数。
fgets.c

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])  
{
        int line = 0;
        char buf[128];
        FILE *fp;
        if (argc < 2)
        {
                printf("Usage : %s <file>\n", argv[0]);
                return -1;
        }
        if ((fp = fopen(argv[1], "r")) == NULL)
        {
                perror("fail to fopen");
                return -1;
        }
        while(fgets(buf, 128, fp) != NULL)
        {
                if (buf[strlen(buf)-1] == '\n')
                line++;
        }
        printf("The line of %s is %d\n", argv[1], line);
        return 0;
}

(i) 以指定大小为单位读写文件

在文件流被打开之后,可对文件流按指定大小为单位进行读写操作。

 

 (j) 每个打开的流内部都有一个当前读写位置。流在打开时,当前读写位置为 0,表示文件的开始位置。每读写一次后,当前读写位置自动增加实际读写的大小。在读写流之间可先对流进行定位,即移动到指定的位置再操作。

 

 下面的例子为获取一个文件的大小。
ftell.c

#include <stdio.h>
int main(int argc, char *argv[])
{
        FILE *fp;
        if (argc < 2)
        {
                printf("Usage : %s <file>\n", argv[0]);
                return -1;
        }
        if ((fp = fopen(argv[1], "r")) == NULL)
        {
                perror("fail to fopen");
                return -1;
        }
        fseek(fp, 0, SEEK_END);
        printf("The size of %s is %ld\n", argv[1], ftell(fp));
        return 0;
}

(k)标准化输入输出函数

4、演示案例详解
a.实验目的
通过对文件进行复制,掌握流的基本操作。
b.实验内容
在程序中分别打开源文件和目标文件。循环从源文件中读取内容并写入目标文件。
c.实验步骤
(1)设计流程。
检查参数→打开源文件→打开目标文件→循环读写文件→关闭文件
(2)编写代码。

#include <stdio.h>
#include <errno.h>
#include <string.h>
#define N 64

int main(int argc, char *argv[])
{
        int n;
        char buf[N];
        FILE *fps, *fpd;
        if (argc < 3)
        {
                printf("Usage : %s <src_file> <dst_file>\n", argv[0]);
                return -1;
        }
        if ((fps = fopen(argv[1], "r")) == NULL)
        {
                fprintf(stderr, "fail to fopen %s : %s\n", argv[1], strerror(errno));
                return -1;
        }
        if ((fpd = fopen(argv[2], "w")) == NULL)
        {
                fprintf(stderr, "fail to fopen %s : %s\n", argv[2], strerror(errno));
                fclose(fps);
                return -1;
        }
        while((n = fread(buf, 1, N, fps)) >= 0)
        {
                fwrite(buf, 1, N, fpd);
        }
        fclose(fps);
        fclose(fpd);
        return 0;
}

跟着例程一个一个字的敲,便对该部分知识有着两三层的理解,大致知道有哪些函数,该如何用。具体用到的时候在返回来研究。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值