C primer plus 文件输入输出不完全整理

* exit()函数关闭所有打开的文件并终止程序。exit()函数的参数会被传递给一些操作系统,包括UNIX、Linux和MS DOS,以供其他程序使用。通常的约定是正常终止的程序传递值0,非正常终止的程序传递非0值。

ANSI C标准规定使用宏EXIT_SUCCESS来指示程序成功终止,使用宏EXIT_FAILURE来指示程序非成功终止。

return  和 exit() 的一个区别在于,即使在除main()之外的函数中调用exit(),它也将终止程序。


* w/w+ 首先将文件长度截为0

rb+ wb ab ab+ a+b wb+ w+b 类似,只是使用二进制模式而非文本模式打开文件


* ch=getc(fp);//从指针fp指定的文件中获取一个字符

putc(ch,fpout);//将字符写入fpout指针指定的文件中

* 文件结尾 getc(fp)==EOF

/* addaword.c -- uses fprintf(), fscanf(), and rewind() */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAX 41

int main(void)

{

    FILE *fp;

    char words[MAX];


    if ((fp = fopen("wordy", "a+")) == NULL)

    {

        fprintf(stdout,"Can't open \"wordy\" file.\n");

        exit(EXIT_FAILURE);

    }


    puts("Enter words to add to the file; press the #");

    puts("key at the beginning of a line to terminate.");

    while ((fscanf(stdin,"%40s", words) == 1)  && (words[0] != '#'))

        fprintf(fp, "%s\n", words);


    puts("File contents:");

    rewind(fp);          /* go back to beginning of file */

    while (fscanf(fp,"%s",words) == 1)

        puts(words);

    puts("Done!");

    if (fclose(fp) != 0)

        fprintf(stderr,"Error closing file\n");


    return 0;

}


// reducto.c -- reduces your files by two-thirds!

#include <stdio.h>

#include <stdlib.h>    // for exit()

#include <string.h>    // for strcpy(), strcat()

#define LEN 40

int main(int argc, char *argv[])

{

    FILE  *in, *out;  // declare two FILE pointers

    int ch;

    char name[LEN];    // storage for output filename

    int count = 0;


    // check for command-line arguments

    if (argc < 2)

    {

        fprintf(stderr, "Usage: %s filename\n", argv[0]);

        exit(EXIT_FAILURE);

    }

    // set up input

    if ((in = fopen(argv[1], "r")) == NULL)

    {

        fprintf(stderr, "I couldn't open the file \"%s\"\n",

                argv[1]);

        exit(EXIT_FAILURE);

    }

    // set up output

    strncpy(name,argv[1], LEN - 5); // copy filename

    name[LEN - 5] = '\0';

    strcat(name,".red");            // append .red

    if ((out = fopen(name, "w")) == NULL)

    {                      // open file for writing

        fprintf(stderr,"Can't create output file.\n");

        exit(3);

    }

    // copy data

    while ((ch = getc(in)) != EOF)

        if (count++ % 3 == 0)

            putc(ch, out);  // print every 3rd char

    // clean up

    if (fclose(in) != 0 || fclose(out) != 0)

        fprintf(stderr,"Error in closing files\n");


    return 0;

}


* fprint()和fscanf()与printf()和scanf()区别不大,关键在于前两个需要第一个参数来指定合适的文件

* fgets()和gets()不一样 他有三个参数 第一个和gets()一样 都是存储输入的地址

fgets(buf, MAX, fp) fgets()函数读取到它所遇到的第一个换行字符的后面,或者读取比字符串的最大长度MAX少一个的字符,

或者读取到文件结尾,然后fgets()函数向末尾添加一个空字符以构成一个字符串。所以,字符串的最大长度代表字符的最大数目再加上一个空字符

如果fgets()函数在达到字符最大数目之前读完了一整行,他将在字符串的空字符之前添加一个换行符以标记一行结束

而gets()读取换行符后将其丢弃,fets()函数可以防止存储溢出

与gets()类似,fgets()遇到EOF会返回NULL

fputs()两个参数,依次是一个字符串的地址和和一个文件指针 与puts()不同,fputs()函数打印时不添加换行符


/* reverse.c -- displays a file in reverse order */

#include <stdio.h>

#include <stdlib.h>

#define CNTL_Z '\032'  /* eof marker in DOS text files */

#define SLEN 81

int main(void)

{

    char file[SLEN];

    char ch;

    FILE *fp;

    long count, last;


    puts("Enter the name of the file to be processed:");

    scanf("%80s", file);

    if ((fp = fopen(file,"rb")) == NULL)

    {                              /* read-only mode  */

        printf("reverse can't open %s\n", file);

        exit(EXIT_FAILURE);

    }


    fseek(fp, 0L, SEEK_END);        /* go to end of file */

    last = ftell(fp);

    for (count = 1L; count <= last; count++)

    {

        fseek(fp, -count, SEEK_END); /* go backward      */

        ch = getc(fp);

if (ch != CNTL_Z && ch != '\r')  /* MS-DOS files */

            putchar(ch);

    }

    putchar('\n');

    fclose(fp);


    return 0;

}


* fseek()第一个参数为FILE指针,第二个为偏移量,第三个为模式(SEEK_SET 文件开始处;SEEK_CUR 文件当前处;SEEK_END 文件结尾处)

偏移量 0L 10L 2L -10L

ftell为long类型 返回文件的当前位置 ftell(fp)


* size_t fwrite(const void * restrict ptr, size_t size, size_t nmemb, FILE * restrict fp) 将二进制数据写入文件

ptr--数据块地址 size--数据块大小(以字节为单位) nmemb--数据块的数目 fp--要写入的文件

size_t fread(const void * restrict ptr, size_t size, size_t nmemb, FILE * restrict fp) 读取通过fwrite()写入的文件数据

ptr--读入文件数据的内存存储地址 fp--要写入的文件

double earnings[10];

fread(earnings, sizeof(double), 10, fp);//该调用将10个double值复制到earnings数组中


* 把多个文件的内容追加到一个文件中

/* append.c -- appends files to a file */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define BUFSIZE 4096

#define SLEN 81

void append(FILE *source, FILE *dest);

char * s_gets(char * st, int n);

int main(void)

{

    FILE *fa, *fs; // fa for append file, fs for source file

    int files = 0;  // number of files appended

    char file_app[SLEN];  // name of append file

    char file_src[SLEN];  // name of source file

    int ch;


    puts("Enter name of destination file:");

    s_gets(file_app, SLEN);

    if ((fa = fopen(file_app, "a+")) == NULL)

    {

        fprintf(stderr, "Can't open %s\n", file_app);

        exit(EXIT_FAILURE);

    }

    if (setvbuf(fa, NULL, _IOFBF, BUFSIZE) != 0)

    {

        fputs("Can't create output buffer\n", stderr);

        exit(EXIT_FAILURE);

    }

    puts("Enter name of first source file (empty line to quit):");

    while (s_gets(file_src, SLEN) && file_src[0] != '\0')

    {

        if (strcmp(file_src, file_app) == 0)

            fputs("Can't append file to itself\n",stderr);

        else if ((fs = fopen(file_src, "r")) == NULL)

            fprintf(stderr, "Can't open %s\n", file_src);

        else

        {

            if (setvbuf(fs, NULL, _IOFBF, BUFSIZE) != 0)

            {

                fputs("Can't create input buffer\n",stderr);

                continue;

            }

            append(fs, fa);

            if (ferror(fs) != 0)

                fprintf(stderr,"Error in reading file %s.\n",

                        file_src);

            if (ferror(fa) != 0)

                fprintf(stderr,"Error in writing file %s.\n",

                        file_app);

            fclose(fs);

            files++;

            printf("File %s appended.\n", file_src);

            puts("Next file (empty line to quit):");

        }

    }

    printf("Done appending. %d files appended.\n", files);

    rewind(fa);

    printf("%s contents:\n", file_app);

    while ((ch = getc(fa)) != EOF)

        putchar(ch);

    puts("Done displaying.");

    fclose(fa);


    return 0;

}

void append(FILE *source, FILE *dest)

{

    size_t bytes;

    static char temp[BUFSIZE]; // allocate once


    while ((bytes = fread(temp,sizeof(char),BUFSIZE,source)) > 0)

        fwrite(temp, sizeof (char), bytes, dest);

}

char * s_gets(char * st, int n)

{

    char * ret_val;

    char * find;


    ret_val = fgets(st, n, stdin);

    if (ret_val)

    {

        find = strchr(st, '\n');  // look for newline

        if (find)                  // if the address is not NULL,

            *find = '\0';          // place a null character there

        else

            while (getchar() != '\n')

                continue;

    }

    return ret_val;

}


* 使用二进制I/O进行随机存取

/* randbin.c -- random access, binary i/o */

#include <stdio.h>

#include <stdlib.h>

#define ARSIZE 1000

int main()

{

    double numbers[ARSIZE];

    double value;

    const char * file = "numbers.dat";

    int i;

    long pos;

    FILE *iofile;


    // create a set of double values

    for(i = 0; i < ARSIZE; i++)

        numbers[i] = 100.0 * i + 1.0 / (i + 1);

    // attempt to open file

    if ((iofile = fopen(file, "wb")) == NULL)

    {

        fprintf(stderr, "Could not open %s for output.\n", file);

        exit(EXIT_FAILURE);

    }

    // write array in binary format to file

    fwrite(numbers, sizeof (double), ARSIZE, iofile);

    fclose(iofile);

    if ((iofile = fopen(file, "rb")) == NULL)

    {

        fprintf(stderr,

                "Could not open %s for random access.\n", file);

        exit(EXIT_FAILURE);

    }

    // read selected items from file

    printf("Enter an index in the range 0-%d.\n", ARSIZE - 1);

    while (scanf("%d", &i) == 1 && i >= 0 && i < ARSIZE)

    {

        pos = (long) i * sizeof(double); // calculate offset

        fseek(iofile, pos, SEEK_SET);    // go there

        fread(&value, sizeof (double), 1, iofile);

        printf("The value there is %f.\n", value);

        printf("Next index (out of range to quit):\n");

    }

    // finish up

    fclose(iofile);

    puts("Bye!");


    return 0;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容