• 嵌入式成长轨迹18 【Linux应用编程强化】【Linux下的C编程 下】【标准输入输出】


    一   标准输入输出的基本操作
    文件控制结构中包含处理文件所需的全部信息,例如文件名、文件当前的读写位置、用于该文件读写的内存缓冲区位置等。打开文件时,系统会在内存中自动建立该文件的控制结构。关闭文件时,文件控制结构被释放。在对文件进行操作之前,要首先获取文件的指针,即指向文件控制结构的指针,后续操作都通过该指针进行。标准输入输出时,有3个比较特殊的文件,它们是:标准输入文件(stdin):一般为键盘;

    标准输出文件(stdout):一般为显示器;

    标准错误输出文件(stderr):一般为显示器。

    1 文件的打开
    操作文件之前要打开文件,打开文件主要是在系统中分配一些资源用于保存该文件的状态信息,并获取文件的指针,以后调用其它函数对文件进行读写操作时都要提供这个指针。

    2 文件的关闭


      FILE *fopen(const char *filename, const char *modes);
    对文件操作完成后,应该关闭文件,进而释放文件所占用的系统资源。文件关闭之后,文件指针将不再有效,用户也就无法通过该指针操作文件。

     int fclose(FILE *fp);

     1 /* example1.c */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 int main()
    5 {
    6 FILE *fp; /* 定义文件指针 */
    7 fp = fopen("./hello.c", "r"); /* 打开文件 */
    8 if (fp == NULL) /* 如果文件打开失败,输出错误信息并退出 */
    9 {
    10 printf("Open hello.c failed.\n");
    11 exit(1);
    12 }
    13 printf("Open file succeed.\n");
    14 fclose(fp); /* 关闭文件 */
    15 return 0;
    16 }


    3 缓冲区的刷新
    刷新操作是指将缓冲区中的数据清除,这项工作可以由fflush或fpurge函数完成。

     int fflush(FILE *fp);
     int fpurge(FILE *fp);
    4 缓冲区属性的设置
    缓冲区的大小和类型等都可以通过函数来设置,缓冲区的类型有下面三种:

    全缓冲:缓冲区被填满后才执行输入输出操作,将数据写入到磁盘文件或输出到用户终端;

    行缓冲:缓冲区中填入换行符时,执行输入输出操作;

    无缓冲:不对数据进行缓存,标准错误输出stderr一般就是无缓冲的,这可以使错误信息尽快地显示出来。

    int setvbuf(FILE *fp, char *buf, int mode, size_t size);


    _IOFBF、_IOLBF、_IONBF


    二  非格式化输入输出
    非格式化输入输出包括单个字节输入输出、字符串(行)输入输出以及数据块输入输出

    1  单个字节输入输出
    在进行单个字节的输入输出操作时,可以使用fgetc函数和fputc函数。

    文件输入输出单个
     int fgetc(FILE *fp);
     int fputc(int c, FILE *fp);

    标准输入单个 int getchar();

     int fgetc(stdin);

    标准输出单个
     int putchar(int c);

     int fputc(c, stdout);

     1 /* example2.c */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 int main()
    5 {
    6 FILE *fp; /* 定义文件指针 */
    7 int ch;
    8 fp = fopen("./tmp", "w+"); /* 打开文件 */
    9 if (fp == NULL)
    10 {
    11 perror("Open tmp failed "); /* 如果文件打开失败,输出错误信息 */
    12 exit(1);
    13 }
    14 while ((ch=getchar()) != '!') /* 从键盘读入字符,直到输入“!”结束 */
    15 {
    16 fputc(ch, fp); /* 将读入的字符写到文件之中 */
    17 }
    18 rewind(fp); /* 重设读写位置 */
    19 while ( (ch=fgetc(fp)) != EOF) /* 将文件内容一个字节一个字节地读出来,直到文件结束 */
    20 {
    21 putchar(ch); /* 将读出的字符输出到屏幕 */
    22 }
    23 fclose(fp);
    24 return 0;
    25 }
     1 /* example4.c */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #define BUFFER_SIZE 256
    5 int main()
    6 {
    7 char buffer[BUFFER_SIZE]; /* 定义缓冲区 */
    8 int c;
    9 FILE *fp; /* 定义文件指针 */
    10 fp = fopen("./hello.c", "r"); /* 打开文件 */
    11 if (fp == NULL)
    12 {
    13 perror("Open hello.c failed "); /* 如果文件打开失败,输出错误信息 */
    14 exit(1);
    15 }
    16 c = 1;
    17 while (fgets(buffer, BUFFER_SIZE, fp) != NULL) /* 逐行读取文件内容 */
    18 {
    19 printf("%d: %s", c++, buffer); /* 输出各行内容 */
    20 }
    21 fclose(fp); /* 关闭文件 */
    22 return 0;
    23 }
     1 /* example5.c */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #define BUFFER_SIZE 256
    5 int main(int argc, char **argv)
    6 {
    7 char buffer[BUFFER_SIZE]; /* 定义缓冲区 */
    8 FILE *fp1, *fp2; /* 定义文件指针 */
    9 if(argc != 3)
    10 {
    11 printf("Too few arguments.\n");
    12 }
    13 fp1 = fopen(argv[1], "r"); /* 打开源文件 */
    14 if (fp1 == NULL)
    15 {
    16 perror("Open file1 failed "); /* 如果文件打开失败,输出错误信息 */
    17 exit(1);
    18 }
    19 fp2 = fopen(argv[2], "w"); /* 打开目标文件 */
    20 if (fp2 == NULL)
    21 {
    22 perror("Open file2 failed "); /* 如果文件打开失败,输出错误信息 */
    23 exit(1);
    24 }
    25 while (!feof(fp1)) /* 测试是否读到文件末尾 */
    26 {
    27 fgets(buffer, BUFFER_SIZE, fp1); /* 逐行读取源文件内容尾 */
    28 fputs(buffer, fp2); /* 逐行写入到目标文件之中 */
    29 }
    30 fclose(fp1); /* 关闭源文件 */
    31 fclose(fp2); /* 关闭目标文件 */
    32 printf("Done!\n");
    33 return 0;
    34 }


    rewind函数
     
     void rewind(FILE * fp);


    fseek函数
     
     int fseek(FILE *fp, long offset, int whence); fseek(fp, 0, SEEK_SET);

     fseek(fp, 0, SEEK_END);

    ftell函数
     
     long ftell(FILE *fp);

     1 /* example3.c */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 int main()
    5 {
    6 FILE *fp; /* 定义文件指针 */
    7 int i, ch, n;
    8 fp = fopen("./tmp", "r"); /* 打开文件 */
    9 if (fp == NULL)
    10 {
    11 perror("Open tmp failed "); /* 如果文件打开失败,输出错误信息 */
    12 exit(1);
    13 }
    14 for (i=0; i<=7; i+=2)
    15 {
    16 fseek(fp, i, SEEK_SET); /* 重设读写位置 */
    17 n = ftell(fp); /* 获取当前的读写位置 */
    18 printf("Position : %ld\n", n+1);
    19 ch=fgetc(fp); /* 从文件读入一个字节 */
    20 printf("Character : ");
    21 putchar(ch); /* 将字符输出到屏幕 */
    22 printf("\n");
    23 }
    24 fclose(fp); /* 关闭文件 */
    25 return 0;
    26 }


    3  数据块输入输出
    对文件进行输入输出操作,也可以以数据块为单位进行。所谓数据块,是指一串固定长度的字节,例如一个整型数据、一个结构体,或一个固定长度的数组等。


     size_t fread(void *ptr, size_t size, size_t n, FILE *fp); size_t fwrite(void *ptr, size_t size, size_t n, FILE *fp);

     1 /* example6.c */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #define N 3
    5 struct student /* 定义结构体 */
    6 {
    7 int id;
    8 int score;
    9 };
    10 int main()
    11 {
    12 struct student array[N]; /* 定义结构体数组 */
    13 int i, n;
    14 FILE *fp; /* 定义文件指针 */
    15 fp = fopen("./test.dat", "w"); /* 打开文件 */
    16 if (fp == NULL)
    17 {
    18 perror("Open test.dat failed "); /* 如果文件打开失败,输出错误信息 */
    19 exit(1);
    20 }
    21 for(i=0; i<N; i++) /* 初始化结构体 */
    22 {
    23 printf("ID : ");
    24 scanf("%d", &array[i].id);
    25 printf("Score : ");
    26 scanf("%d", &array[i].score);
    27 }
    28 n = fwrite(array, sizeof(struct student), N, fp); /* 将结构体数组写入到文件之中 */
    29 if (n != N)
    30 {
    31 printf("Write file error"); /* 如果写入失败,输出信息 */
    32 }
    33 fclose(fp); /* 关闭文件 */
    34 return 0;
    35 }
     1 /* example7.c */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 #define N 3
    5 struct student /* 定义结构体 */
    6 {
    7 int id;
    8 int score;
    9 };
    10 int main()
    11 {
    12 struct student x[N]; /* 定义缓冲区 */
    13 int i, n;
    14 FILE *fp; /* 定义文件指针 */
    15 fp = fopen("./test.dat", "r"); /* 打开文件 */
    16 if (fp == NULL)
    17 {
    18 perror("Open test.dat failed "); /* 如果文件打开失败,输出错误信息 */
    19 exit(1);
    20 }
    21 n = fread(x, sizeof(struct student), N, fp); /* 从文件中读取N个结构体 */
    22 if (n != N) /* 如果实际读取长度小于N,输出具体原因 */
    23 {
    24 if(feof(fp)) /* 测试是否读到文件末尾 */
    25 {
    26 printf("End of file.");
    27 }
    28 else
    29 {
    30 printf("Read file error"); /* 输出错误信息 */
    31 }
    32 }
    33 printf("ID\tScore\n");
    34 for (i=0; i<N; i++)
    35 {
    36 printf("%d\t%d", x[i].id, x[i].score); /* 输出各结构体数组 */
    37 printf("\n");
    38 }
    39 fclose(fp); /* 关闭文件 */
    40 return 0;
    41 }



    三  格式化输入输出
    格式化输出的函数

     int fprintf(FILE *fp, const char *format, ... );
     int printf(const char *format, ... );

     int fprintf(stdout, const char *format, ... );

    format: % [+/-] [0] [m.n] [l] 转换字符
    1.转换字符

    2.指定输出精度 l

    3. m.n
    指定输出长度
    如: 
     double x=0.123;
     printf("%9.4f\n", x);
      0.1230
    9是总长度
    这里空位补空格

    4.空位填零 0
      int x=123;
      printf("%06d\n", x);
      000123

    5.指定输出位置 + -
    默认右对齐,加入-则可左对齐

    char c[]=“ABCD”;
    printf("%-5.3s\n", a);
    printf("%+5.3s\n", a);

    ABC
      ABC
     

    格式化输入的函数

     int fscanf(FILE *fp, const char *format, ... );

     
     int scanf(const char *format, ... );
     
     int fscanf(stdin, const char *format, ... );
     

     scanf("%d %d", &x, &y);
     
     scanf("%d, %d", &x, &y);
     
     scanf("%10s", s); 10是读入总长度

     1 /* example13.c */
    2 #include <stdio.h>
    3 #include <stdlib.h>
    4 int main()
    5 {
    6 int x;
    7 int sum = 0;
    8 while (scanf("%d", &x) == 1) /* 读入整数,赋给变量x */
    9 {
    10 sum += x; /* 累加 */
    11 printf("\t%3d\n", sum); /* 输出结果 */
    12 }
    13 return 0;
    14 }


    其它应用

     1 /* example14.c */
    2 #include <stdio.h>
    3 #include <stdarg.h>
    4 int sum(int num, ...) /* 求和 */
    5 {
    6 int v, i;
    7 int sum = 0;
    8 va_list vp; /* 定义指向可变参数列表的指针 */
    9 va_start(vp, num); /* 使指针指向参数列表中的第一个可选参数 */
    10 i = num;
    11 while(i > 0)
    12 {
    13 v = va_arg(vp, int); /* 返回指针所指向的参数,并将其后移 */
    14 sum += v;
    15 i--;
    16 }
    17 va_end(vp);
    18 return sum;
    19 }
    20 int main()
    21 {
    22 printf("%d\n", sum(2, 2, 3)); /* 输出计算结果 */
    23 printf("%d\n", sum(4, 1, 2, 3, 4));
    24 return 0;
    25 }
     1 /* example15.c */
    2 #include <stdio.h>
    3 #include <stdarg.h>
    4 int myprintf(char *format, ...) /* 定义可变参数函数 */
    5 {
    6 va_list vp; /* 定义指向可变参数列表的指针 */
    7 int n;
    8 va_start(vp, format); /* 使指针指向参数列表中的第一个可选参数 */
    9 n = vprintf(format, vp); /* 调用vprintf函数,通过va_list传入输入参数 */
    10 va_end(vp);
    11 return n;
    12 }
    13 int main(void)
    14 {
    15 int x = 30;
    16 float y = 0.36;
    17 char *z = "abc";
    18 myprintf("x = %d\ny = %g\nz = %s\n", x, y, z); /* 调用前面定义的printf函数,将数据输出到屏幕 */
    19 return 0;
    20 }



    四   常见面试题
    常见面试题1:调用fgets函数从文件中读取字符时,函数在满足什么条件时返回?


    常见面试题2:调用fprintf函数进行格式化输出时,如何指定输出的长度和对齐方式?

  • 相关阅读:
    2017蓝桥杯最大公共子串(C++B组)
    C++ memset函数用法
    2017蓝桥杯取位数(C++B组)
    2017蓝桥杯承压计算(C++ B组)
    安卓动画(Animation使用)
    2017蓝桥杯等差素数(C++B组)
    JSON取值前判断
    jstl
    centos到底下载哪个版本?
    HTML页面定时跳转方法
  • 原文地址:https://www.cnblogs.com/zeedmood/p/2417019.html
Copyright © 2020-2023  润新知