C语言:关于文件的相关操作函数总结

1.文本文件与二进制文件的操作

文本文件就是把每一个字符的ASCII码存放到文件中

二进制文件就是把数据对应的二进制形式存储到文件中

1.1打开文件:

FILE* fopen(const char* filename,const char* mode);

(1)函数参数:

    filename:文件名

    mode:文件打开的权限,权限包括如下:

模式含义
“r”只读
“w”只写
“a”文件末尾只写
“r+”在读的基础上增加可写的功能
“w+”向文件中写入数据,然后可读取文件的内容
“a+”文件末尾只写,并且可以读
“rb”二进制只读
“wb”二进制只写
“ab”二进制文件尾只写
“rb+”二进制文件在读的基础上增加可写的功能
“wb+”向二进制文件中写入数据,然后可读取文件的内容
“ab+”

二进制文件末尾只写,并且可以读

(2)返回值:

    打开成功返回FILE类型的指针,打开失败返回NULL

1.2关闭函数:

int fclose(FILE* stream)

(1)函数参数:

    stream:指向需要关闭流的指针

(2)返回值:

    关闭成功返回0,关闭失败返回-1 

1.3字符串格式化函数:

int sprintf(char*  str,const char* format,……)

(1)函数参数:

    str:指向缓冲区的指针,是将format里面的格式化字符串写入此缓冲区

    format:格式化字符串,同printf的格式规范相同

    ……:附加参数

(2)返回值:

    成功返回写入的字符总数,失败返回负数

(3)示例:

#include<stdio.h>
int main()
{
    char buff[128];
    int val=100;
    sprintf(buff,"val = %d\n",val);//此时会将字符串"val = 100\n\0"写入buff数组中,一共占11字节
    return 0;
}

1.4文本文件的读写

1.4.1格式化写入函数:

int fprintf(FILE*  stream,const char* format,……)

(1)函数参数:

    stream:将format里面的格式化字符串写入到stream流中

    format:格式化字符串

    ……:附加参数

(2)返回值:

    成功返回写入的字符总数,失败返回负数

(3)示例:

#include<stdio.h>
int main()
{
    int ar[]={12,23,34};
    int n=sizeof(ar)/sizeof(ar[0]);
    FILE* fd=open("text.txt","w");
    if(fd==nullptr)
    {
        printf("打开文件失败");
        exit(EXIT_FAILURE);
    }
    for(int i=0;i<n;++i)
    {
         fprntf(fd,"%d",ar[i]);//将ar数组里面的元素转为字符存储到fd这个文件描述符所指向的text.ext文本文件中
    }
    close(fd);
    fd=nullptr;
    return 0;
}

1.4.2从流中读取格式化数据函数

int fscanf(FILE* stream,const char* format,……)

(1)函数参数:

    stream:从stream这个流中读取数据

    format:格式化字符串,遵循scanf的格式规范

    ……:附加参数

(2)返回值

    成功返回接收参数的数量,失败返回-1

(3)示例:

#include <stdio.h>
#define SIZE 10
int main()
{
    FILE* fd=fopen("text.txt","r");
    if(fd==nullptr)
    {
        printf("打开文件失败");
        exit(EXIT_FAILURE);
    }
    const int n=10;
    int br[n]={0};
    for(int i=0;i<n;++i)
    {
        fscanf(fd,"%d",&br[i]);//从fd这个文件描述符所指的ext.txt文件中读出数据,以"%d"这种数字的格式存储到br数组中
    }
    fclose(fd);
    fd=nullptr;
    return 0;
}

1.5二进制文件的读写

1.5.1二进制文件的写入函数

size_t fwrite(const void* ptr,size_t size,size_t count,FILE* stream);

(1)函数参数:

    prt:从ptr指向的地址获取内容从而写入到stream这个流中

    size:单位元素的大小

    count:总共的元素数

    stream:指向被写入的流

(2)返回值:

成功返回写入元素的个数,如果失败,返回的元素个数会小于count

(3)示例:

#include <stdio.h>
int main()
{
    FILE* fdw=fopen("text,txt","wb");
    if(fdw==nullptr)
    {
        printf("打开文件失败");
        exit(EXIT_FAILURE);
    }
    int ar[]={12,23,34,45};
    int n=sizeof(ar)/sizeof(ar[0]);
    //将ar这个数组里面的所有元素以二进制的形式写入到fdw所指向的文件中
    fwrite(ar,sizeof(int),n,fdw);
    fclose(fdw);
    fdw=nullptr;
    return 0;
}

1.5.2二进制文件的读出函数

size_t fread(const void* ptr,size_t size,size_t count,FILE* stream);

(1)函数参数:

    prt:从stream这个流中读取内容存放到ptr所指的地址

    size:单位元素的大小

    count:总共的元素数

    stream:需要读取内容的流

(2)返回值:

成功返回读取元素的个数,如果失败,返回的元素个数会小于count

(3)示例:

#include <stdio.h>
int main()
{
    FILE* fdr=fopen("text,txt","rb");
    if(fdr==nullptr)
    {
        printf("打开文件失败");
        exit(EXIT_FAILURE);
    }
    int n=10;
    int ar[n]={0};
    //读取fdr所指向的二进制文件,读取sizeof(int)*n个字节,一次存放到ar数组中
    fread(ar,sizeof(int),n,fdr);
    fclose(fdr);
    fdr=nullptr;
    return 0;
}

2.缓冲和非缓冲文件的操作

缓冲文件就是指从内存向磁盘输出数据先存放到缓冲区,装满后再放到磁盘。反向亦如此。

非缓冲文件就是直接将数据从内存输出到磁盘,中间不经过缓冲区

2.1清除读写缓冲区

int fflush(FILE* stream)

(1)函数参数:

 stream:指向输出流或者更新流,fflush函数会把任何未被写入的数据写入stream指向的文件,比如stdout。

(2)返回值:

如果成功刷新或者指定的流没有缓冲区,又或者以只读可打开文件的时候返回0

返回EOR(表示-1)则会指出一个错误

(3)常见用法:

fflush(stdin):刷新标准输入缓冲区,把标准输入缓冲区里面的数据丢弃掉(注释:并非所有编译器都支持此功能,因为C/C++的标准里面并没有定义此用法,所以使用fflush(stdin)并不是正确的方式)

fflush(stdout):刷新标准输出缓冲区,把输出缓冲区里面的东西打印到标准输出设备上

2.2把缓冲区与流相关

之所以需要把缓冲区和流相关的目的在于:使用fopen\fread\fwrite\fprintf\fscanf函数的时候,会直接在内存中操作,减少内存到磁盘IO读写的操作次数,从而提高系统利用率。比如程序设计到使用数据库、视频、音频等大量爆发式磁盘到内存的IO情况,可以使用setvbuf优化内存IO。需要注意的是:linux\windows会自动处理这些问题。

2.2.1void setbuf(FILE* stream,char* buffer)

(1)函数功能:

设置流操作的内部缓冲区,长度至少为BUFSIZE个字符,这个函数应该在打开流后,立即调用,在任何对该流做输入输出前

需要注意一下几点:

①如果buffer不为空,等价于setvbuf(stream,buffer,_IOFBF,BUFSIZE)

②如果buffer为空,则等价于setvbuf(stream,NULL,_IONBF,0)

③避免需要使用缓冲区的内容时,因为作用域的原因导致缓冲区被释放了,例如:

int main()
{
     char buff[128];
     setbuf(stdout,buff);
     int x;
     while(x=(getchar())!=EOF)
     {
          putchar(x);//将输入的内容先从放到buff的缓冲区中,然后等到缓冲区满再输出
     }
}

上述程序是错误的,原因是如果缓冲区buff没有被放满,就不会输出,但是由于输入的x=-1,退出循环,程序结束,就会将buff里面的内容释放,所以无法将之前输入的内容正常输出。因此应该注意缓冲区的生存期。

(2)函数参数:

stream:要设置缓冲区的文件流

buffer:指针指向需要用到的缓冲区,如果指向NULL,表示不需要缓冲区

(3)示例:

int main()
{
    char buff[1024];
    FILE* fd=open("text.txt","w");
    int a=100,b=200;
    //把变量a,b通过字符串的形式先写入缓冲区buff中,然后再从缓冲区中写入到fd所指向的文件内部
    setbuf(fd,buff);
    fprintf(fd,"a = %d,b = &=%d\n",a,b);
    fclose(fd);
    fd=nullptr;
    return 0;
}

2.2.2 int setvbuf(FILE* stream,char* buffer,int mode,size_t size);

(1)函数功能:

此函数的功能和setbuf差不多,只不过由于参数的不同,所以setvbuf可以指定缓冲区的大小

使用此函数还需要注意如下几点:

①当buffer为空,可以通过mode、size来重置内部缓冲区的大小

②当buffer不为空,可以通过mode、size来设置提供的buffer这个缓冲区的大小

③这个函数应该在打开流后,立即调用,在任何对该流做输入输出前

(2)函数参数:

stream:要设置缓冲的文件流

buffer:指向缓冲区

mode:缓冲模式

           _IOFBF:全缓冲(当缓冲区满时在想流写入数据)

           _IOLBF:行缓冲

           _IONBF:无缓冲

size:缓冲区的大小

(3)返回值:

成功返回0,失败返回非零

3.文件位置操作

3.1返回当前文件位置的指示值

long ftell(FILE* stream)

(1)参数:

stream:要检验的文件流

(2)返回值:

成功时返回文件位置指示器,失败则为-1L

3.2获取文件位置指示器

int fgetpos(FILE* stream,fpos_t *pos)

(1)函数作用:

将stream文件流的位置指针保存到pos这个位置变量中

(2)参数:

stream:要检验的文件流

pos:指向要存储文件位置指示器到fpos_t对象的指针

(3)返回值:

成功返回0

失败返回非零值

(4)示例:

int main()
{
     //打开text.txt文件,文件事先会有一定的内容
     FILE* fd=fopen("text,txt","w");
     fpos_t pos;
     //使用fgetpos函数取得文件指针的位置,并存到Pos中,此时pos=0
     fgetpos(fd,pos);
     printf("当前的文件指针在第%ld个字节",pos);
     //将文件位置偏移3,也就是指向文件的第4个字节
     fseek(fd,3,0);
     //此时pos的值为3
     fgetpos(fd,pos);
     printf("当前的文件指针在第%ld个字节",pos);
     fclose(fd);
     return 0;
}

3.3将文件位置指示符移动到文件指定位置

3.3.1 int fseek(FILE* stream,long offset,int origin)

可以用fseek()和ftell()来计算文件的长度

#include <stdio.h>
int main()
{
     FILE* fd=fopen("text,txt","r");
     fseek(fd,0,SEEK_END);//将文件描述符移动到尾部
     ftell(fd);//得出文件描述符的位置就是文件的大小
     close(fd);
     return 0;
}

(1)函数参数:

stream:要修改的文件流

offset:相对origin所移动的字符数

origin:offset以origin为基础位置进行移动,包括:
          SEEK_SET:文件开头

          SEEK_CUR:当前位置

          SEEK_END:文件结尾

(2)返回值

成功时返回0,失败返回非0

(3)示例:

fseek(fd,100L,SEEK_SET):把fd指针移动到从文件开始位置计算往后100个字节的地方

fseek(fd,100L,SEEK_CUR):把fd指针移动到从文件当前位置计算往后100个字节的地方

fseek(fd,0L,SEEK_END):定位到文件结尾处

fseek(fd,-100L,SEEK_END):从文件结尾回退100字节

3.3.2 int fsetpos(FILE* stream,const fpos_t* pos)

(1)函数参数:

stream :要修改的文件流

pos:指向fpos_t对象的指针,用作文件位置指示器的新值

(2)函数返回值:

成功返回0,否则非零

3.4将文件位置指示器移动到文件首

void rewind(FILE* stream)

(1)函数作用:

移动文件描述符到文件的开始位置,等价于fseek(fd,0,SEEK_SET);

4.错误处理

4.1清除错误

void clearerr(FILE* stream)

(1)函数作用:

把文件结束符EOF和错误标识符从非0值变为0值

(2)函数参数:

stream:要重置错误标志的文件流

(3)示例:

int main()
{
    FILE* fd=fopen("text.txt","r");//打开一个文件,这个文件里面是有内容的
    //如果此文件的结尾不是EOF结尾,就会退出程序不再执行后序操作
    assert(feof(fd));
    
    int ch;
    //读到文件结尾遇到EOF就退出循环
    while((ch=fgetc(fd))!=EOF)
    {
        printf("%c",ch);
    }
    clearerr(fd);//将错误标志从非0变为0
    //如果没有设置文件结束符eof就会返回0,否则返回非0,上面将EOF设置为0,说明此文件没有课文件结束符,因此feof(fd)会返回0,执行else语句
    if(feof(fd))
    {
        printf("文件有结束符\n");
    }
    else
    {
        printf("文件没有结束符\n");
    }
}

4.2检查文件结尾

int feof(FILE* stream)

(1)函数作用:

检查是否抵达文件流的结尾

(2)函数参数:

stream:要检验的文件流

(3)返回值:

如果已经到结尾返回非零值,否则返回0

4.3检查文件错误

int ferror(FILE* stream)

(1)函数作用:

检查给定文件流的错误

(2)返回值:若文件流已经出现错误则返回非零值,否则返回0

(3)示例:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    FILE* fd=fopen("text.txt","r");
    int c;//使用
    while((c=fgetc(fd))!=EOF)
    {
        putchar(c);
    }
    
    //ferror()与feof()分别用来区别不同的错误条件
    if(ferror(fd))
    {
        printf("读取的时候发生错误\n");
    }
    else if(feof(fd))
    {
        printf("成功读取到文件末尾\n");
    }
    fclose(fd);

}

4.4显示对应当前错误的字符串到stderr

void perror(const char* s)

(1)函数作用:

用来将上一个函数发生错误的原因输出到标准设备stderr。然后会打印出:s所指向的字符串+错误原因字符串。

5.文件操作

5.1删除文件

int remove(const char* fname);

(1)函数作用:

删除fname这个文件名所对应的文件

(2)函数参数:

fname:待删除文件的名字(包含路径)

(3)返回值:
成功返回0,失败返回非0

5.2重命名文件

int rename(const char* old_filename,const char* new_filename);

更改文件的名字,前面的参数是原来名字,后面的参数是更改之后的文件名字

5.3返回指向临时文件的指针

5.3.1FILE* tmpfile(void)

(1)函数作用:

创建唯一的临时二进制文件(类型为wb+),并打开此文件

(2)返回值:

成功返回文件流,失败返回空

5.3.2char* tmpnam(char* s)

(1)函数作用:

生成唯一临时文件名

使用fopen创建临时文件,文件关闭,使用remove函数来删除该文件

(2)函数参数:

s指向一个char类型的数组,这个数组里面存放临时文件的名称,如果s为空,就会使用一个内部静态数组来存储临时名称。

(3)返回值:

成功时返回文件名字的指针,失败返回空

6.无格式输入、输出

6.1从文件流获取一个字符

int fgetc(FILE* stream)

int getc(FILE* stream)

(1)返回值:

成功时为获取的字符,失败返回EOF

(2)fegtc和getc的区别:

fgetc()是一个函数,getc()是一个宏,宏调用的时候参数不能是副作用表达式(副作用表达式:表达式执行完之后会改变其中某些变量的值,比如++i就是一个副作用表达式)

6.2从文件流中获取一个字符串

char* fgets(char* str,int count,FILE* stream)

(1)函数作用:
从stream这个指针所指向的文件中获取count-1个字符存放到str的字符数组中,成功时返回str,失败返回空指针

6.3将一个字符写入文件流

int fputc(int ch,FILE* stream)

int putc(int ch,FILE* stream)

(1)函数作用:

将字符ch写到stream文件流中。

(2)返回值:

成功时返回被写入的字符

失败返回EOF并设置stream上的错误指示器

6.4将一个字符串写入文件流

int fputs(const char* str,FILE* stream);

int fputs(const char* restrict str,FILE* restrict stream)

(1)函数作用:

将以NULL结尾的字符串str的每个字符写入到stream文件流中

(2)参数:

str:要写入的字符串

stream:输出流

(3)返回值:

成功时返回非负值,失败时返回EOF

(4)注意:

函数int puts(const char* str,FILE* stream)会将换行符附加到str字符串中输出给stream文件流中

而fputs写入的字符串并不会进行修改

6.5从stdin读取一个字符

int getchar(void)

(1)返回值:

成功时为获得的字符,失败时为EOF

6.6从stdin读取一个字符串

char* gets_s(char* str,rsize_t n)

(1)函数说明:

从stdin里面读取n-1个字符存储到str中,不存在缓冲区,然后遇到换行或者符或者文件尾,就会去掉换行符,并附加空字符。

(2)返回值:

成功时返回str指针,失败返回空指针

(3)备注:

fgets()函数不进行边界检查,从而导致此函数对缓冲区溢出攻击极度脆弱,无法安全使用,所以被弃用。

6.7将一个字符写入stdout

int putchar(int ch);

(1)返回值:

成功时返回写入的字符,失败返回EOF并设置stdout上的错误指示器

(2)说明:

putchar()函数的参数ch必须是处于0-127之间的一个十进制整数

如果整型ch超出八位变量的范围时,ch则会被强转为8位变量(取低八位)

如果整型ch为负数的时候,由于计算机存储负数是补码的方式,所以会被当做正数处理,也是取低八位

(3)示例:

int main()
{
     int res=0;
     for(char c='a';(c!=EOF)&&(c!='z');++c)
     {
          res=putchar(c);
     }
     if(res==EOF)
     {
          if(ferror(stdout))
          {
                fprintf(stderr,"putchar() failed\n");
                perror("putchar()");
                exit(EXIT_FAILURE);
          }
     }
     putchar("\n");
     
      
     //验证超出八位的字符输出结果是否和参数一样——答案肯定是不一样的
     int x=0x1070;
     printf("\n0x%x\n",r);
     x=putchar(x);
     printf("\n0x%x\n",r);
}

6.8将一个字符串写入stdout

int puts(const char* str)

(1)函数参数

str:要写入的字符串

(2)返回值

成功返回非负值,失败返回EOF

6.9将一个字符退回文件流

int ungetc(int ch,FILE* stream);

(1)函数说明:

将ch字符放到流stream的输入缓冲区,从而能够从stream的后继读取该字符,而不会修改与流关联的外部设备。

(2)参数

ch:要推入输入流缓冲区的字符

stream:要回放字符到文件流

(3)返回值:

成功返回ch,失败返回EOF

(4)说明:

①使用fseek\fsetpos\rewind将会忽略ungetc所加入的字符

②如果调用一次ungetc之后,不读取或者不重新寻位,然后再次调用ungetc就有可能调用失败,因为回放缓冲区大小可能位1)

③如果成功调用多次ungect,读取操作以ungect的逆序取得回访的字符

④如果ch=EOF,操作失败不会影响流

⑤实践中,回放缓冲区的大小会在4K和A或者保证的最小值1之间变化

(5)示例:

int main()
{
     int res=0;
     char ch;
     printf("请输入整数:\n");
     while((ch=getchar())!=EOF&&isdigit(ch))
     {
         res=res*10+ch-'0';
     }
     if(ch!=EOF)
     {
          ungect(ch,stdin);//将字符ch退回到输入流
     }
     printf("%d,uninteger--%c\n",res,(char)(getchar()));
     return 0;
}


/*
请输入整数:
666x
//输出:
666 uninteger--x
*/

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 文件读写是C语言中非常常见的操作。以下是一个简单的文件读写操作的示例代码: ```c #include <stdio.h> int main() { // 写入文件 FILE *fp = fopen("example.txt", "w+"); if (fp == NULL) { printf("Failed to open file.\n"); return 1; } fprintf(fp, "Hello, world!\n"); fclose(fp); // 读取文件 fp = fopen("example.txt", "r"); if (fp == NULL) { printf("Failed to open file.\n"); return 1; } char buffer[1024]; while (fgets(buffer, 1024, fp)) { printf("%s", buffer); } fclose(fp); return 0; } ``` 上述代码中,我们使用了 `fopen` 函数打开了一个名为 `example.txt` 的文件,并指定了文件打开模式为 `w+`,表示以读写方式打开文件。如果文件打开失败,我们就输出一条错误信息,并返回 1。接着,我们使用 `fprintf` 函数文件中写入了一个字符串。最后,我们使用 `fclose` 函数关闭了文件。 接下来,我们又使用了 `fopen` 函数打开了同一个文件,并指定了文件打开模式为 `r`,表示以只读方式打开文件。如果文件打开失败,我们就输出一条错误信息,并返回 1。接着,我们使用 `fgets` 函数读取文件中的每一行,并将其保存在 `buffer` 数组中。最后,我们使用 `printf` 函数将 `buffer` 中的内容输出到控制台中。最后,我们再次使用 `fclose` 函数关闭了文件。 需要注意的是,以上代码中使用的是 `fprintf` 和 `fgets` 函数,它们与 `printf` 和 `scanf` 函数非常类似,只不过它们需要指定要读写的文件对象。此外,我们还需要注意在读取文件时,要使用 `fgets` 函数而不是 `fscanf` 函数,因为前者可以读取一整行,而后者只能读取单个单词。 ### 回答2: 文件读写操作C语言中常用的操作之一,通过文件读写操作可以实现数据的持久化存储和读取。下面是一个简单的C语言文件读写操作的示例代码: ```c #include <stdio.h> int main() { // 定义文件指针 FILE *file; // 打开文件并判断是否成功打开 file = fopen("data.txt", "w"); if (file == NULL) { printf("文件打开失败\n"); return 1; } // 写入数据 fprintf(file, "Hello, world!"); // 关闭文件 fclose(file); // 重新打开文件以读取数据 file = fopen("data.txt", "r"); if (file == NULL) { printf("文件打开失败\n"); return 1; } // 读取数据并输出到控制台 char buffer[100]; while (fgets(buffer, sizeof(buffer), file)) { printf("%s", buffer); } // 关闭文件 fclose(file); return 0; } ``` 上述代码首先打开一个名为"data.txt"的文件进行写入操作,然后重新打开同一文件进行读取操作,并将读取到的数据输出到控制台。在实际使用时,可以根据具体需求进行文件路径设置、读写数据内容的修改等操作。 注意,在使用文件读写操作时,要确保文件的权限正确,并且要注意文件是否成功打开和关闭,以免出现错误。 ### 回答3: C语言中,要进行文件读写操作,首先需要包含头文件"stdio.h"。 (一)文件操作: 要从文件中读取数据,首先需要打开文件,然后使用fopen函数来打开指定的文件,语法如下: FILE *fopen(const char *filename, const char *mode); 其中,filename是要打开的文件名,mode是文件的打开模式,常用的模式有:r(只读)、w(只写)、a(追加)等。 例如,要以只读方式打开名为"example.txt"的文件,可以使用以下代码: ```c FILE *file = fopen("example.txt", "r"); ``` 文件打开成功后,可以利用fscanf、fgets等函数文件中读取数据。 例如,使用fscanf函数读取文件中的一个整数,并打印出来: ```c int num; fscanf(file, "%d", &num); printf("%d", num); ``` 读取完文件中的数据后,需要使用fclose函数关闭文件,防止资源泄漏,语法如下: int fclose(FILE *stream); 例如: ```c fclose(file); ``` (二)文件操作: 要向文件中写入数据,同样需要打开文件。使用fopen函数来打开文件,并指定打开模式为"w"或"a"。 接着,使用fprintf、fputc等函数将数据写入文件中。 例如,向名为"example.txt"的文件中写入一个字符串: ```c FILE *file = fopen("example.txt", "w"); fprintf(file, "Hello, World!"); fclose(file); ``` 上述代码会打开文件并将字符串"Hello, World!"写入文件中,然后关闭文件总结C语言中的文件读写操作需要先打开文件,然后读写数据,最后关闭文件。 通过使用fopen、fclose等函数,可以完成文件的打开和关闭。 而使用fscanf、fgets等函数读取文件数据,使用fprintf、fputc等函数写入文件数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仟各

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值