c和c++的输入输出汇总

一、引言

      本文将对c语言的标准IO的输入输出函数和c++标准库的输入输出流进行详细汇总,如果什么有缺漏和错误,欢迎各位网友指出,我会立马更新~

二、c语言标准IO库

1、fgetc、getc、getchar

作用:从文件中获取一个字符

头文件:#include <stdio.h>

原型: int fgetc(FILE *stream);

       int getc(FILE *stream);

       int getchar(void);  //专门用于stdin

参数:stream:文件指针

返回值:成功:读取到的字符   失败:EOF(-1)

备注:当返回EOF时,文件可能是已到达末尾,或者出错。另外,上面的函数,如果输入的是标准输入流stdin(键盘的输入),那么它们会阻塞程序,等待用户完成键盘输入;如果是普通文件,它们是不会阻塞的。

2、fputc、putc、putchar

作用:将一个字符输入到文件中

头文件:#include <stdio.h>

原型: int fputc(int c,FILE *stream);

          int putc(int c,FILE *stream);

       int putchar(int c); //专门用于stdout

参数:c:要输入的字符  stream:文件指针

返回值:成功:输入的字符指针  失败:EOF

备注:fgetc和fputc、getc和putc、getchar和putchar一般成对使用。

示例代码:

#include <stdio.h>
int main(){
    FILE* fp;
    char x;
    fp = fopen("./hello.txt","r+"); 
    if(fp == NULL){
        perror("打开文件失败\n");
        return -1;
    }
    while(1){
        x = fgetc(fp);
        if(x == EOF){
            //由于返回EOF的结果可能是到文件末尾,可能是出错,那么怎么区别呢?
            if(feof(fp)){ //feof判断末尾
                putchar('\n'); //输出完毕后换行
                break;
            }
            else
                return -1;
        }
        putchar(x);
    }
    fclose(fp);
    return 0;
}

3、fgets、gets

作用:从制定文件中读取最多一行数据

头文件:#include <sys/ioctl.h>

原型: char* fgets(char* s,int size,FILE* stream);

       char* gets(char* s); //默认从stdin读

参数:s:自定义缓冲区指针  size:缓冲区大小

stream:要读取数据的文件指针

返回值:成功:自定义缓冲区指针s  失败:NULL

备注:由于gets没有指定缓冲区的大小,所以容易造成缓冲区溢出,接口过时。在fgets中,实际上最多读取的字符数是size-1,因为缓冲区的末尾需要一个’\0’占位。

4、fputs、puts

作用:将字符串输出到文件中

头文件:#include <sys/ioctl.h>

原型:int fputs(const char* s, FILE* stream);

      int puts(const char* s); //默认输出到stdout

参数:s:自定义缓冲区  stream:即将被写入数据的文件指针

返回值:成功:非负整数  失败:EOF

示例代码:

#include <stdio.h>
#include <sys/ioctl.h>

int main(){
    FILE* fp;
    FILE* result;
    char buf1[20];
    fp = fopen("./hello.txt","r+");
    result = fopen("./result.txt","r+");
    if(fp == NULL || result == NULL){
        return -1;
    }
    fgets(buf1,sizeof(buf1),fp);
    fputs(buf1,result);
    fclose(fp);
    fclose(result);
    return 0;
}

5、fread

作用:从指定文件读取若干个数据块

头文件:#include <sys/ioctl.h>

原型:size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream)

参数:ptr:自定义缓冲区指针大小  size:数据块大小

         nmenb:数据块个数  stream:被读取数据的文件指针

返回值:成功:读取的数据块个数,等于nmenb

              失败:小于nmemb,或等于0

备注:当数据块不是刚好读完时,返回的值是向下取整的,比如:要读取大小是100字节,块数是5的空间,但实际大小是499个字节,那么返回值是4,因为最后一块没有满,此时如果和fwrite()搭配使用的时候,要特别注意,需要额外处理。

6、fwrite

作用:将若干数据块写入文件

头文件:#include <sys/ioctl.h>

原型:size_t fwrite(const void* ptr, size_t size, size_t nmemb,

FILE* stream)

参数:ptr:缓冲区指针  size:块的大小

            nmemb:块的数量  stream:写入的文件

返回值:成功:写入的数据块个数,等于nmemb

              失败:小于nmemb,或等于0

备注:size和nmemb要合理设计,以防止写入额外的无用数据

示例代码:

#include <sys/ioctl.h>
#include <stdio.h>
#define SIZE 512
#define NUM 2
/*
    代码实现文件拷贝的功能
*/
int main(){
    FILE* fp_source;
    FILE* fp_to;
    char buf[SIZE*NUM];
    int pre_pos,last_pos;

    fp_source = fopen("./hello.txt","r+");
    fp_to = fopen("./result.txt","r+");
    if(fp_source==NULL || fp_to==NULL){
        return -1;
    }
    while(1){
        pre_post = ftell(fp_source); //获取文件的位置偏移量
        if(fread(buf,SIZE,NUM,fp_source) < NUM){
            //末尾未满块的处理
            if(feof(fp_source)){
                last_pos = ftell(fp_source);
                fwrite(buf,pre_pos-last_pos,1,fp_to);  
                break;
            }
            else{
                return -1;
            }
        }
        fwrite(buf,SIZE,NUM,fp_to);
    }
    fclose(fp_source);
    fclose(fp_to);
    return 0;
}

7、fprintf、printf、snprintf、sprintf

作用:将格式化的数据写入指定的文件或者内存

头文件:#include <stdio.h>

原型:int fprintf(FILE* restrict stream, const char* restrict format,…)

         int printf(const char* restrict format, …)

         int snprintf(char* restrict s, size_t n, const char* restrict format, …)

        int sprintf(char* restrict s,size_t n, const char* restrict format,…)

参数:stream:写入数据的文件指针   format:格式控制串

         s:写入数据的自定义缓冲区   n:自定义的缓冲区大小

返回值:成功:成功写入的字节数  失败:-1

备注:由于sprintf没有指定缓冲区的大小,所以有溢出的风险,相比之下,snprintf更好。

示例:

#include <stdio.h>

int main(){
    char buf[30];
    int a = 10;
    char b = 90;
    char temp[20]="hello world";
    snprintf(buf,30,"%d + %d = %s",a,b,temp);
    puts(buf);
    return 0;
}

8、fscanf、scanf、sscanf

作用:从指定的文件或者内存中读取格式化的数据

头文件:#include <stdio.h>

原型:int fscanf(FILE* restrict stream, const char* restrict format,…)

         int scanf(const char* restrict format,…)

            int sscanf(const char* restrict s,const char* restrict format, …)

参数:stream:读出数据的文件指针  format:格式控制串

         s:读出数据的自定义缓冲区

返回值:成功:正确匹配且赋值的数据个数

              失败:EOF

备注:fscanf函数有些难点是对“分隔符”的识别和在换行时对“换行符”的处理,经过本人多次验证,发现如果你使用“空格”作分隔符,那么该函数会自动处理换行符,但是如果使用其它分隔符,会出现bug,所以本人建议最好使用空格作换行符,而且允许数据之间的空格出现多次,该函数会当成一个空格处理。

示例:

#include <stdio.h>

int main() {
  FILE *file = fopen("hello.txt", "r");
  if (file == NULL) {
    return -1;
  }

  char name[20];
  char sex;
  int age;
  float height;
  //使用空格作为换行符
  while (fscanf(file, "%s %c %d %f", name,&sex,&age,&height) != EOF) {
    // 处理读取到的数据
    printf("%s %c %d %.1f\n", name,sex,age,height);
  }

  fclose(file);
  return 0;
}

三、c++标准IO库

在c++中,由于引入了流对象,所以IO库的使用主要是cin、cout的成员函数的使用。有关输入输出流的具体介绍,可以看我另一篇文章,本文知汇总一些常用的成员函数。

1、get

作用:在输入流中获取单个字符或字符串

头文件:#include <iostream>

原型:int get();

istream& get(char& var);

istream& get ( char* s, streamsize n );

istream& get ( char* s,  streamsize  n, char delim );

参数:var:存放字符的变量  s:存放字符串的缓冲区指针

            n:允许读入字节个数        delim:自定义结束符

返回值:第一个函数:

                  成功:获取的字符  失败:EOF

              其余函数:

                  成功:输入流对象,一般是cin(为了支持链式输入操作)

                  失败:失败式的流对象,可以用cin.fail()检测

备注:前两个是单个字符的获取,分隔符按普通字符处理;后两个是字符串的读取,遇到换行符(默认)或者自定义结束符时,结束读取,但是换行符或自定义结束符会残留在缓冲区,注意下次使用时的缓冲区清除的细节。

示例:

#include <iostream>
#include <fstream>
using namespace std;

int main(){
    char a;
    char b;
    fstream fp;
    fp.open("./hello.txt",ios_base::in|ios_base::out); //打开文件,可读可写
    a = cin.get(); //从标准输入流中获取单个字符
    b = fp.get(); //从文件流中获取单个字符
    cout<<a<<" "<<b<<endl;

    char arr1[20];
    char arr2[20];
    cin.get(arr1,20); //从标准输入流中获取字符串,遇到换行符或满20个字符结束
    fp.get(arr2,20);//从文件流中获取字符串,遇到换行符或满20个字符结束
    cout<<arr1<<endl<<arr2<<endl;

    cin.get(arr1,20,' ');//从标准输入流中获取字符串,遇到空格或满20个字符结束
    fp.get(arr2,20,' ');//从文件流中获取字符串,遇到空格或满20个字符结束
    cout<<arr1<<endl<<arr2<<endl;

    fp.close();
    return 0;
}

2、getline(成员函数)

作用:在输入流中获取一行字符串

头文件:#include <iostream>

原型:istream& getline(char* s, streamsize count);

istream& getline(char* s, streamsize count, char delim);

参数:s:缓冲区指针  count:允许读入字节个数

            delim:自定义结束符

返回值:成功:输入流对象,一般是cin(为了支持链式输入操作)

              失败:失败式的流对象,可以用cin.fail()检测

备注:getline和get的后两个相似,不同是:cin.getline不会将结束符或者换行符残留在输入缓冲区中,所以当按行读取字符串时,建议使用getline函数。

示例:

#include <iostream>
using namespace std;

int main(){
    char arr[20];
    cin.getline(arr,20);
    cout<<arr<<endl;
    return 0;
}

3、getline(普通函数)

作用:在输入流中获取一行字符串

头文件:#include <string>

原型:istream& getline ( istream& is, string& str);

istream& getline ( istream& is, string& str, char delim);

参数:is:输入流对象,比如cin  str:自定义缓冲区

            delim:自定义结束符

返回值:成功:输入流对象,一般是cin(为了支持链式输入操作)

              失败:失败式的流对象,可以用cin.fail()检测

备注,getline的成员函数和普通函数的作用完全一样,只是用法不同,还有使用的字符串缓冲区不同,前者是char*,后者是string

示例:

#include <string>
#include <iostream>
using namespace std;

int main()
{
    string str;
    getline(cin,str);
    cout<<str<<endl;
    return 0;
}

4、其余接口

      由于c++有关输入输出流的接口太多,难以一一列举,但是我们要掌握其核心,就是为流对象服务的,要想实现某种功能,只需要查看相应流类给出的成员函数有哪些。

        下面给出一个很方便查找相关成员函数的网址:std::basic_fstream - cppreference.com

    

      都读到这里了,还不给个赞?你的点赞支持,是我持续写作的动力~

格式控制符表格

格式控制符

含义

%d

有符号十进制整型数

%u

无符号十进制整型数

%o

无符号八进制整型数

%x

无符号十六进制整型数

%c

字符

%s

字符串

%f

计数法单精度浮点数

%e

科学计数法单精度浮点数

%p

指针

%.5s

取字符串前5个

%.5f

保留小数点后五位

%5d

位宽最少5个字符,右对齐

%-5d

位宽最少5个字符,左对齐

%hd

半个有符号数十进制整型数

%hhd

半半个有符号数十进制整型数

%lf  %le

双精度浮点数

%Lf  %Le

长双精度浮点数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值