C/C++开发,无可避免的IO输入/输出(篇四).c实现浅述

目录

一、C-IO

二、文件操作IO

三、字符串流(内存流)IO

四、设备抽象IO


一、C-IO

        c语言的IO输入/输出是由标准库<stdio.h>提供,见名知意,stdio就是标准库(std)的IO模块。<stdio.h> 头文件提供通用文件操作支持并提供有窄字符输入/输出能力的函数。针对与宽字符,增加了<wchar.h> 作为辅助,该头文件提供有宽字符输入/输出能力的函数。c语言的I/O 流为 FILE 对象所代表,只能通过 FILE* 类型指针访问及操作。每个流与外部物理设备(文件、标准输入流、打印机、序列端口等)关联。

        下来看看stdio的主要功能:

//定义于头文件 <stdio.h>
FILE      对象类型,足以保有控制 C I/O 流所需的全部信息(typedef) 
fpos_t    非数组完整对象类型,足以唯一指定文件的位置和多字节剖析状态(typedef) 

//预定义标准流
stdin     与标准输入流关联的 FILE* 类型表达式(宏常量) 
stdout    与标准输出流关联的 FILE* 类型表达式(宏常量) 
stderr    与标准错误输出流关联的 FILE* 类型表达式(宏常量) 

//函数,文件访问
fopen      (C11)打开文件(函数) 
fopen_s    (C11)打开文件(函数) 

freopen    (C11)以不同名称打开既存的文件流(函数) 
freopen_s  (C11)以不同名称打开既存的文件流(函数) 

fclose     关闭文件(函数) 
fflush     将输出流与实际文件同步(函数) 
setbuf     为文件流设置缓冲区(函数) 
setvbuf    为文件流设置缓冲区和其大小(函数) 

//直接输入/输出
fread    从文件读取(函数) 
fwrite   写入到文件(函数) 

//无格式输入/输出,窄字符
fgetc    从文件流获取一个字符(函数) 
getc     从文件流获取一个字符(函数) 

fgets    从文件流获取一个字符串(函数) 
fputc    将一个字符写入文件流(函数) 
putc     将一个字符写入文件流(函数) 
fputs    将一个字符串写入文件流(函数) 

getchar  从 stdin 读取一个字符(函数) 
gets     (C11 中移除)从 stdin 读取一个字符串(函数) 
gets_s   (C11)从 stdin 读取一个字符串(函数) 
putchar  将一个字符写入 stdout(函数) 
puts     将一个字符串写入 stdout(函数) 
ungetc   将一个字符送回文件流(函数) 

//有格式输入/输出,窄字符 
scanf        从stdin、文件流或缓冲区读取格式化输入(函数) 
fscanf       ...
sscanf       ... 
scanf_s      (C11)...
fscanf_s     (C11)...
sscanf_s     (C11)...

vscanf       (C99)从 stdin 、文件流或缓冲区读取格式化输入 使用可变参数列表(函数) 
vfscanf      (C99)...
vsscanf      (C99)...
vscanf_s     (C11)...
vfscanf_s    (C11)...
vsscanf_s    (C11)...

printf      打印格式化输出到 stdout 、文件流或缓冲区(函数) 
fprintf     ...
sprintf     ...
snprintf    (C99)...
printf_s    (C11)...
fprintf_s   (C11)...
sprintf_s   (C11)...
snprintf_s  (C11)...

vprintf     打印格式化输出到stdout、文件流或缓冲区 使用可变参数列表(函数) 
vfprintf    ...
vsprintf    ...  
vsnprintf   (C99)...
vprintf_s   (C11)...
vfprintf_s  (C11)...
vsprintf_s  (C11)...
vsnprintf_s (C11)...

//文件位置
ftell       返回当前的文件位置指示值(函数) 
fgetpos     获取文件位置指示器(函数) 
fseek       将文件位置指示符移动到文件中的指定位置(函数) 
fsetpos     将文件位置指示器移动到文件中的指定位置(函数) 
rewind      将文件位置指示器移动到文件首(函数) 

//错误处理
clearerr   清除错误(函数)
feof       检查文件结尾(函数) 
ferror     检查文件错误(函数) 
perror     显示对应当前错误的字符串到 stderr(函数) 

//文件操作
remove     删除文件(函数) 
rename     重命名文件(函数) 
tmpfile    返回指向临时文件的指针(函数)
tmpfile_s  (C11) ...
tmpnam     返回唯一的文件名(函数) 
tmpnam_s   (C11) ...
 
//宏常量
EOF            int 类型的负值整数常量表达式(宏常量) 
FOPEN_MAX      能同时打开的文件数(宏常量) 
FILENAME_MAX   保有最长受支持文件名所需的 char 数组大小(宏常量)
BUFSIZ         setbuf() 所用的缓冲区大小(宏常量) 
_IOFBF         指示全缓冲 I/O 的 setvbuf() 参数(宏常量)
_IOLBF         指示行缓冲 I/O 的 setvbuf() 参数(宏常量)
_IONBF         指示无缓冲 I/O 的 setvbuf() 参数(宏常量)

SEEK_SET       指示从文件首开始寻位的 fseek() 参数(宏常量) 
SEEK_CUR       指示从文件当前位置开始寻位的 fseek() 参数(宏常量)
SEEK_END       指示从文件尾开始寻位的 fseek() 参数(宏常量) 

TMP_MAX        tmpnam 所能生成的最大独有文件数(宏常量) 
TMP_MAX_S      (C11)tmpnam_s 所能生成的最大独有文件数(宏常量) 
L_tmpnam       保有 tmpnam 结果所需的 char 数组大小(宏常量) 
L_tmpnam_s     (C11)保有 tmpnam_s 结果所需的 char 数组大小(宏常量) 

二、文件操作IO

        一般来说,文件操作有以下步骤:

  1. 定义文件指针,并打开文件;
  2. 通过文件指针进行读写操作;
  3. 关闭文件。

        以下是一个简单的例子,演示如何实现文件的输入输出操作:

//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    char ch, filename[10];
    printf("请输入文件名:");
    scanf("%s", filename);
    fp = fopen(filename, "w"); // 以写入方式打开文件,如果文件不存在则新建文件
    if (fp == NULL)
    {
        printf("无法打开文件\n");
        exit(0);
    }
    printf("请输入内容:\n");
    while ((ch = getchar()) != EOF) // 从键盘读取字符,直到EOF结束
    {
        fputc(ch, fp); // 将字符写入到文件中
    }
    fclose(fp); // 关闭文件
    printf("写入成功\n");

    fp = fopen(filename, "r"); // 以读取方式打开文件
    if (fp == NULL)
    {
        printf("无法打开文件\n");
        exit(0);
    }
    printf("读取内容:\n");
    while ((ch = fgetc(fp)) != EOF) // 从文件中读取字符,直到EOF结束
    {
        putchar(ch); // 将字符输出到屏幕
    }
    fclose(fp); // 关闭文件
    return 0;
}

        该代码会提示用户输入文件名,然后以写入方式打开文件,将用户从键盘输入的内容写入到文件中。接着,以读取方式打开同一个文件,将文件中的内容读取并输出到屏幕上。可以通过运行该程序,查看文件的输入输出是否成功。

三、字符串流(内存流)IO

        C语言中没有内置的字符串流(string stream)功能,但是可以通过以下方法手动模拟:

        1.创建一个缓冲区作为字符串流的输出源

char buffer[1024]; // 创建一个大小为1024的缓冲区

        2.使用sprintf将需要输出的数据格式化到缓冲区中

int x = 10;
float y = 3.14;
char str[] = "hello";
sprintf(buffer, "x=%d, y=%.2f, str=%s", x, y, str);

        3.从缓冲区中读取字符串流数据

char result[1024];
strcpy(result, buffer);

        以上是一种基本的手动模拟字符串流的方式。如果你需要更多类似C++中字符串流的高级功能,比如重载运算符、自定义输入/输出运算符等,可以使用C++编写。

四、设备抽象IO

        C语言的设备抽象IO主要就是与命令窗口的交互,主要是通过预定义标准流来实现的,

stdin     与标准输入流关联的 FILE* 类型表达式
stdout    与标准输出流关联的 FILE* 类型表达式
stderr    与标准错误输出流关联的 FILE* 类型表达式  
 

        预定义标准流本质上就是FILE*指针操作,可以使用标准库中的stdio.h头文件提供的函数来进行屏幕输入/输出操作,常用的有printf函数、scanf函数等。

        printf函数可以输出格式化的文本,用于向屏幕输出内容:

//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>

int main(void) {
    printf("Hello, world!\n");
    return 0;
}

        而fprintf可以将全局stdout、stderr 等FILE*类型指定输出

//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>

int main(void) {
    fprintf(stdout,"Hello, world!\n");
    return 0;
}

        scanf函数可以读取从屏幕输入的数据,并将数据存储到变量中:

//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>

int main(void) {
    int num;
    printf("Enter a number: ");
    scanf("%d", &num);
    printf("You entered: %d\n", num);
    return 0;
}

        当然,类似地,fscanf可以从全局stdin等FILE*类型指定输入

//main.c,gcc main.c -o test.exe -std=c11
#include <stdio.h>

int main(void) {
    int num;
    printf("Enter a number: ");
    fscanf(stdin,"%d", &num);
    printf("You entered: %d\n", num);
    return 0;
}

        除了以上两个函数,C语言还提供了很多其他的屏幕输入/输出函数,比如puts函数、gets函数、fgets函数、puts函数等,可以根据具体的需求选择使用。

        而对于屏幕输入输出适用的函数对于文件操作就更适用了,比较屏幕输入输出本质上就FILE*类型的操作。

猜你喜欢

转载自blog.csdn.net/py8105/article/details/129909470