MyException - 我的异常网
当前位置:我的异常网» Windows » 必不可少 Windows Native (10)

必不可少 Windows Native (10)

www.MyException.Cn  网友分享于:2015-04-28  浏览:0次
不可或缺 Windows Native (10)

[源码下载]


不可或缺 Windows Native (10) - C 语言: 文件



作者:webabcd


介绍
不可或缺 Windows Native 之 C 语言

  • 文件



示例
cFile.h

#ifndef _MYHEAD_FILE_
#define _MYHEAD_FILE_ 

#ifdef __cplusplus  
extern "C"
#endif  

char *demo_cFile(char *rootPath);

#endif  


cFile.c

/*
 * 文件
 *
 * 从用户角度讲,文件可分为普通文件和设备文件两种
 * 1、普通文件是指保存在磁盘或其它外部介质上的一段数据
 * 2、设备文件是指与主机相联的各种外部设备,操作系统会把各种外部设备也看作是一个文件来进行管理。比如:通常把显示器定义为标准输出文件,键盘定义为标准输入文件
 *
 * 从文件编码的方式来看,文件可分为 ASCII 码文件(文本文件)和二进制文件
 * 1、ASCII 文件也称为文本文件,这种文件在磁盘中存放时每个字符对应一个字节,用于存放对应的 ASCII 码。比如:字符串 1234567 按字符存放成文本文件,占用 7 个字节
 * 2、二进制文件是按二进制的编码方式来存放文件的。比如:数字 1234567 按整型存放成二进制文件,占用 4 个字节
 *
 * 关于 mkdir(make directory) - 创建目录,rmdir(remove directory) - 删除目录 之类的函数,以后再写
 *
 *
 * 注:EOF(end of file) - 文件的结束标志
 */

#include "pch.h"
#include "cFile.h"
#include "cHelper.h"

void file_demo1();
void file_demo2();
void file_demo3();
void file_demo4();
void file_demo5();

char *_rootPath;

char *demo_cFile(char *rootPath)
{
    _rootPath = rootPath;

    // 写入文本文件
    file_demo1();

    // 读取文本文件
    file_demo2();

    // 以格式化的方式读写文本文件
    file_demo3();

    // 读写二进制文件
    file_demo4();

    // 文件的内部定位(随机读写,即任意位置读写)
    file_demo5();

    return str_concat2("演示文件的保存路径:", rootPath);
}


// 写入文本文件
void file_demo1()
{
    // 文件指针 - 指向文件的指针(FILE *指针变量标识符)


    // 需要访问的文件路径
    char *fileName = str_concat2(_rootPath, "\\c_file_demo1.txt");

    // fopen - 用指定的方式打开指定路径的文件,并返回文件指针(FILE 是由系统定义的结构体,fp 是指向 FILE 的文件指针)
    FILE *fp = fopen(fileName, "wt+"); // 第 2 个参数是文件打开方式,其说明参见后面的注释
    if (fp == NULL)
    {
        // 如果 fopen 返回空指针,则说明文件打开失败(errno 中保存着最近一次的错误)
        int errNum = errno; // 关于 errno 的预定义参见 errno.h
    }
    else
    {
        // rewind - 让指定的文件指针所指文件的内部位置指针移到文件头
        rewind(fp);

        // fputc - 向指定的文件写入字符(这里的 EOF 代表写入失败)
        if (fputc('w', fp) == EOF) 
        {
            // ferror - 检查文件在读写时是否出错,返回值为 0 表示正常,否则表示有错
            int errNum = ferror(fp); // 关于 errno 的预定义参见 errno.h

            // clearerr - 清除出错标志,使它为 0 值。
            clearerr(fp);
        }

        // fputs - 向指定的文件写入字符串(这里的 EOF 代表写入失败)
        if (fputs("ebabcd\nwanglei", fp) == EOF)
        {
            // ferror - 检查文件在读写时是否出错,返回值为 0 表示正常,否则表示有错
            int errNum = ferror(fp); // 关于 errno 的预定义参见 errno.h

            // clearerr - 清除出错标志,使它为 0 值。
            clearerr(fp);
        }

        // fclose - 打开文件后,必须要用 fclose 关闭文件,返回 0 则说明文件正常关闭了
        int fcloseResult = fclose(fp);
    }

    free(fileName);
}


// 读取文本文件
void file_demo2()
{
    char *fileName = str_concat2(_rootPath, "\\c_file_demo1.txt");

    FILE *fp = fopen(fileName, "rt");
    if (fp == NULL)
    {
        int errNum = errno;
    }
    else
    {
        rewind(fp);

        // fgetc - 一个字符一个字符地读,如遇到 EOF 则文件读完或出错(每个文件末尾都有结束标志 - EOF)
        char ch = fgetc(fp);
        while (ch != EOF)
        {
            // 每读一个字符,则内部位置指针会向后移动一个字节
            ch = fgetc(fp); 
        }

        // feof - 检查文件是否结束(即内部位置指针是否指向 EOF),如结束,则返回非零值,否则返回 0
        int isEnd = feof(fp); // 非零值

        rewind(fp);

        // feof - 检查文件是否结束(即内部位置指针是否指向 EOF),如结束,则返回非零值,否则返回 0
        isEnd = feof(fp); // 0

        /*
         * fgets(str, n, fp) - 读取字符串函数
         *     str - 字符数组名,由于保存读取到的字符串
         *     n - 读出 n-1 个字符并送入字符数组 str 中,然后在结尾加'\0'(在读出 n-1 个字符之前,如遇到了换行符或 EOF,则读取结束)
         *     fp - 文件指针
         */
        char str[32];
        while (fgets(str, 32, fp) != NULL)
        {
            // 本例会循环 2 次
            // 第 1 次 str 的结果为:webabcd\n
            // 第 2 次 str 的结果为:wanglei
        }

        fclose(fp);
    }

    free(fileName);
}


// 以格式化的方式读写文本文件
void file_demo3()
{
    char *fileName = str_concat2(_rootPath, "\\c_file_demo2.txt");

    FILE *fp = fopen(fileName, "wt+");
    if (fp == NULL)
    {
        int errNum = errno;
    }
    else
    {
        // fprintf(file print formatted) - 以格式化的方式写入字符串(返回值为写入的字节数)
        int fprintfResult = fprintf(fp, "%s %d %d\n", "webabcd", 100, 20); // 15

        rewind(fp);

        int num;
        int age;
        char name[32];

        // fscanf(file scan formatted) - 以格式化的方式读取字符串(返回值为读取的成员数)
        int fscanfResult = fscanf(fp, "%s %d %d\n", name, &num, &age); // 3

        fclose(fp);
    }

    free(fileName);
}


// 读写二进制文件
void file_demo4()
{
    struct employee
    {
        int num;
        char name[32];
    } w[2] = { { 100, "wanglei" }, { 200, "webabcd" } }, r[2], *ww, *rr;

    ww = w;
    rr = r;

    char *fileName = str_concat2(_rootPath, "\\c_file_demo3.b");

    FILE *fp = fopen(fileName, "wb+");
    if (fp == NULL)
    {
        int errNum = errno;
    }
    else
    {
        /*
         * fwrite(buffer, size, count, fp) - 写入二进制数据(返回值为成功写入的数据块数)
         *     buffer - 需要写入的数据的指针
         *     size - 每一个数据块的字节数
         *     count - 需要写入的数据块数
         *     fp - 文件指针
         */
        int fwriteResult = fwrite(ww, sizeof(struct employee), 2, fp); // 2

        rewind(fp);

        /*
         * fread(buffer, size, count, fp) - 读取二进制数据(返回值为成功读取的数据块数)
         *     buffer - 需要保存读取数据的指针
         *     size - 每一个数据块的字节数
         *     count - 需要读取的数据块数
         *     fp - 文件指针
         */
        int freadResult = fread(rr, sizeof(struct employee), 2, fp);

        fclose(fp);
    }

    free(fileName);
}


// 文件的内部定位(随机读写,即任意位置读写)
void file_demo5()
{
    struct employee
    {
        int num;
        char name[32];
    } w[2] = { { 100, "wanglei" }, { 200, "webabcd" } }, r[1], *ww, *rr;

    ww = w;
    rr = r;

    char *fileName = str_concat2(_rootPath, "\\c_file_demo4.b");

    FILE *fp = fopen(fileName, "wb+");
    if (fp == NULL)
    {
        int errNum = errno;
    }
    else
    {
        int fwriteResult = fwrite(ww, sizeof(struct employee), 2, fp);

        /*
         * rewind(fp) - 把文件内部位置指针移到文件头
         *     fp - 文件指针
         */
        rewind(fp);

        /*
         * fseek(fp, offset, origin) - 移动文件内部位置指针
         *     fp - 文件指针
         *     offset - 相对于 origin 的位移字节数(长整形,如果用常量的话记得加“L”)
         *     origin - 位移起始点
         *         SEEK_SET(0) - 文件头
         *         SEEK_CUR(1) - 当前位置
         *         SEEK_END(2) - 文件尾
         */
        fseek(fp, sizeof(struct employee), SEEK_SET);

        int freadResult = fread(rr, sizeof(struct employee), 1, fp); // 200, "webabcd"

        fclose(fp);
    }

    free(fileName);
}



/*
 * 关于文件打开方式的说明,即 fopen 的第 2 个参数 
 * rt     只读打开一个文本文件,只允许读数据
 * wt     只写打开或建立一个文本文件,只允许写数据
 * at     追加打开一个文本文件,并在文件末尾写数据
 * rb     只读打开一个二进制文件,只允许读数据
 * wb     只写打开或建立一个二进制文件,只允许写数据
 * ab     追加打开一个二进制文件,并在文件末尾写数据
 * rt+     读写打开一个文本文件,允许读和写
 * wt+     读写打开或建立一个文本文件,允许读写
 * at+     读写打开一个文本文件,允许读,或在文件末追加数据
 * rb+     读写打开一个二进制文件,允许读和写
 * wb+     读写打开或建立一个二进制文件,允许读和写
 * ab+     读写打开一个二进制文件,允许读,或在文件末追加数据
 *
 * 关于上面字符的说明
 * r(read)        读
 * w(write)        写
 * a(append)    追加
 * t(text)        文本文件,可省略不写
 * b(binary)    二进制文件
 * +            读和写
 */



OK
[源码下载]

1楼garbageMan
引用// 读写二进制文件,……, FILE *fp = fopen(fileName, quot;wt+quot;);,这个荒唐
Re: webabcd
@garbageMan,:),多谢指出问题,已经把t改成b了

文章评论

亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
鲜为人知的编程真相
鲜为人知的编程真相
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
老程序员的下场
老程序员的下场
10个调试和排错的小建议
10个调试和排错的小建议
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
编程语言是女人
编程语言是女人
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
程序员都该阅读的书
程序员都该阅读的书
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
总结2014中国互联网十大段子
总结2014中国互联网十大段子
中美印日四国程序员比较
中美印日四国程序员比较
程序员的鄙视链
程序员的鄙视链
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
一个程序员的时间管理
一个程序员的时间管理
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
那些争议最大的编程观点
那些争议最大的编程观点
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
旅行,写作,编程
旅行,写作,编程
我的丈夫是个程序员
我的丈夫是个程序员
 程序员的样子
程序员的样子
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
每天工作4小时的程序员
每天工作4小时的程序员
程序员和编码员之间的区别
程序员和编码员之间的区别
我是如何打败拖延症的
我是如何打败拖延症的
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
如何成为一名黑客
如何成为一名黑客
程序员应该关注的一些事儿
程序员应该关注的一些事儿
为什么程序员都是夜猫子
为什么程序员都是夜猫子
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
漫画:程序员的工作
漫画:程序员的工作
Java程序员必看电影
Java程序员必看电影
程序员必看的十大电影
程序员必看的十大电影
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有