专栏首页DBA随笔C++里面的文件处理方法

C++里面的文件处理方法

C++里面的文件处理方法

01 文件的fopen函数和fprintf函数 今天在对一些待审核SQL进行语法解析的时候,使用到了C++编程语言,从毕业开始,好久没有动过C++了,工作后一致沉迷在Python的简洁方便中无法自拔。今天有一个打印语法树的需求,想用C++实现一把,所以就回忆了一下C++里面将内容打印到文件的方法,但是在实现的时候,还是摆脱不了C语言的影响,今天先给出C风格完整的代码,后续补充上C++里面的标准输入输出流的代码,算是一个小的总结吧。

1.将特定的字符串写入到一个文件中(C风格):

#include "stdafx.h"
#include "string"
#include "iostream"
#include "stdio.h"
using namespace std;

int file_write(const char* tempstr)
{
    FILE *fp;
    int i;

    fp = fopen("E:/file/data.txt", "w");
    if (fp == NULL)
    {
        printf("File cannot open! ");
        exit();
    }

    char d[];
    sprintf(d,"%s", tempstr);
    fprintf(fp, "%s\t", d);
    printf("writted!\n");

    fclose(fp);
    return ;
}

int main()
{    
    const char* tempstr = "hello,world";
    file_write(tempstr);
    return ;
}

上面的代码中,file_write是一个函数,它接受一个常量指针,然后将这个值打印到一个data.txt的文件中。这里对代码中的一些小的点进行解释:

FILE* fp是一个FILE类型的指针变量;

sprintf指的是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中,sprintf是个变参函数。使用sprintf 对于写入buffer的字符数是没有限制的,这就存在了buffer溢出的可能性,它的返回值是写入的字符数,如果写入"hello,world",则返回值是11;

fprintf和sprintf类似,不过fprintf是写入到一个文件中。

关于fopen函数后面跟的文件操作类型,这里给出一个表格:

关于文件的使用方法,还有如下几点需要注意:

对于文件使用方式有以下几点说明:

1) 文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:

r(read): 只读

w(write): 只写

a(append): 追加

t(text): 文本文件,可省略不写

b(binary): 二进制文件

+: 读和写

2) 凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。

3) 用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。

4) 若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。如果指定文件不存在则尝试创建该文件。

5) 在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。因此常用以下程序段打开文件:

当我在vs2015中对上面的代码进行编译的时候,碰到了下面这个小问题,这里贴出来大家了解下:

'fopen': This function or variable may be unsafe. 
Consider using fopen_s instead. To disable deprecation, 
use _CRT_SECURE_NO_WARNINGS. See online help for details.    
file_operation    
    d:\program files (x86)\myproject\file_operation\file_operation.cpp    15  

这个错误是说fopen函数不安全,如果想要使用的话,请在预处理器中添加_CRT_SECURE_NO_WARNINGS来回避。

02

文件读取fread和fwrite函数

文件读取和文件写入类似,这里也给出一段代码,来介绍文件的读取方法,具体代码如下:

int file_read_and_write()
{
    FILE*stream;
    char msg[] = "this is a test";
    char buf[];
    if ((stream = fopen("E:/file/data.txt", "w+")) == NULL)
    {
        fprintf(stderr, "Can not open output file.\n");
        return ;
    }
    /*write some data to the file*/
    fwrite(msg, , strlen(msg) + , stream);
    /*sizeof(char)=1 seek to the beginning of the file*/
    fseek(stream, , SEEK_SET);
    /*read the data and display it*/
    fread(buf, , strlen(msg) + , stream);

    printf("%s\n",buf);
    fclose(stream);
    return ;
}


int main()
{    
    const char* tempstr = "hello,world";    
    file_read_and_write();
    return ;
}

上面的例子首先打开文件data.txt,然后写入this is a test这个测试字符串,将文件指针设置到文件头,然后读取文件里面的内容,这里再解释下fread和fwrite函数:

fread()函数:

fread是一个函数,它从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回 0

buffer:用于接收数据的内存地址

size:要读的每个数据项的字节数,单位是字节

count要读count个数据项,每个数据项size个字节.

stream:输入流

返回值:返回真实读取的项数,若大于count则意味着产生了错误。另外,产生错误后,文件位置指示器是无法确定的。

fwrite()函数:

fwrite() 是 C 语言标准库中的一个文件处理函数,功能是向指定的文件中写入若干数据块,如成功执行则返回实际写入的数据块数目。该函数以二进制形式对文件进行操作,不局限于文本文件。

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

返回值:返回实际写入的数据块数目

(1)buffer:是一个指针,对fwrite来说,是要获取数据的地址;

(2)size:要写入内容的单字节数;

(3)count:要进行写入size字节的数据项的个数;

(4)stream:目标文件指针;

(5)返回实际写入的数据项个数count。

输出结果如下:

本文分享自微信公众号 - DBA随笔(gh_acc2bbc0d447)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-01-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Vue开始使用NUXT框架开发

    Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如服务端渲染、SEO、中间件支持、布局支持等。

    剑行者
  • Android混淆设置

    对sighed APK进行代码混淆和精简,从而使得发布的代码可以防止被别人反编译解析。

    剑行者
  • C++ std::isnan等函数的使用

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    ccf19881030
  • 怎样使用Carthage

    CocoaPods发展到现在基本上已经是ios开发的标准依赖工具,我们只需要安装好pod后在项目中新建一个Podfile文件并且写入你需要的三方框架,就能很方便...

    剑行者
  • 论PR | Innovus 中cell density计算解析

    在Innovus 中可用如下命令来report density, 不同命令的应用场景和计算方式有所不同。

    老秃胖驴
  • Docker 自定义Dockerfile构建镜像

    -v /data/wwwroot/tomcat01/ROOT/static/:/data/wwwroot/tomcat01/ROOT/static/配置是项目...

    剑行者
  • ios的动态库和静态库

    当你创建一个framework文件时,系统“默认”是一个动态库的格式,如果想做成静态库,需要在buildSetting中将Mach-O Type选项设置为Sta...

    剑行者
  • Sonar Scanner系列之架构与Java篇

    本文系列将介绍Sonar在实际工程项目中落地的场景,例如: 1)多语言项目的扫描,如JAVA/JS/C++/C#/PLSQL 2)多分支扫描 3)覆盖率如何统计...

    Criss@陈磊
  • go-web 服务端框架性能测试

    由于K8s缘故涉猎go语言,发现golang的web框架很多,都号称高性能标杆;之前一直致力于c++高性能服务端框架研究,出于好奇,想单从性能层面客观比较一下g...

    用户2103032
  • 【Rust日报】 2019-10-15 使Tokio调度程序快10倍

    在v0.2我们实现了所有运算符和可视线程的安全性之后,RxRust现在可以通过调度程序跨线程传递任务。这样,所有用户提供的闭包都必须满足Send + Sync ...

    MikeLoveRust

扫码关注云+社区

领取腾讯云代金券