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

#include

#include

#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

#include     // for exit()

#include     // 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

#include

#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

#include

#include

#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

#include

#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;

}

你可能感兴趣的:(C primer plus 文件输入输出不完全整理)