11.02.2015

Linux C fopen(), fclose(), fread(), fwrite(), fseek(), ftell(), rewind()

人啊,年紀越大,就越容易健忘,有些東西明明就是以前有學過,但因為不常使用,所以就慢慢地被遺忘了....

並沒有打算要分別介紹這7個關於檔案讀寫的函式,直接把這些函式組成一個範例,順便加上一些註解,方便以後自己複習。
// f_ctrl.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int 
main()
{
    FILE *fp0 = (FILE *)NULL, *fp1 = (FILE *)NULL;
    char szTemp[4];

    fp0 = fopen("Read.TXT", "rt");
    if (fp0 == NULL) {
        printf("Open \"Read.TXT\" failed!! \n");
        fclose(fp0);
        exit(EXIT_FAILURE);
    }
    fp1 = fopen("Write.TXT", "w+");
    if (fp1 == NULL) {
        printf("Open \"Write.TXT\" failed!! \n");
        fclose(fp1);
        exit(EXIT_FAILURE);
    }

    memset(&szTemp, '\0', sizeof(char) * 4);
    fseek(fp0, 5L, SEEK_SET);
    // Start at '5' at 1st line
    fread((void *)&szTemp, sizeof(char), 4, fp0);
    fwrite((void *)&szTemp, sizeof(char), 4, fp1);
    // szTemp = {'5', '6', '7', '8'};
    szTemp[4 - 1] = '\0';
    // szTemp = {'5', '6', '7', '\0'};
    printf("Position0: %ld, %s \n", ftell(fp0), (char *)szTemp);
    // Position must be: '9' at 1st line.
 
    memset(&szTemp, '\0', sizeof(char) * 4);
    fseek(fp0, -1L, SEEK_CUR);
    // Start at '8' at 1st line
    fread((void *)&szTemp, sizeof(char), 4, fp0);
    fwrite((void *)&szTemp, sizeof(char), 4, fp1);
    // szTemp = {'8', '9', '\n', '9'}'
    szTemp[4 - 1] = '\0';
    // szTemp = {'8', '9', '\n', '\0'}'
    printf("Position1: %ld, %s \n", ftell(fp0), (char *)szTemp);
    // Position must be: '8' at 2nd line.
 
    memset(&szTemp, '\0', sizeof(char) * 4);
    fseek(fp0, -6L, SEEK_END);
    // Start is '5' at 2nd line
    fread((void *)&szTemp, sizeof(char), 4, fp0);
    fwrite((void *)&szTemp, sizeof(char), 4, fp1);
    // szTemp = {'5', '4', '3', '2' };
    szTemp[4 - 1] = '\0';
    // szTemp = {'5', '4', '3', '\0' };
    printf("Position2: %ld, %s \n", ftell(fp0), (char *)szTemp);
    // Position must be: '1' at 2nd line.

    fseek(fp0, 0L, SEEK_END);
    printf("The last position: %ld \n", ftell(fp0));
    // Get the last position
 
    rewind(fp0);    // fseek(fp0, 0L, SEEK_SET);
    printf("The position after rewind(): %ld \n", ftell(fp0));
    // Set the position to start

    fclose(fp0);
    fclose(fp1);

    exit(EXIT_SUCCESS);
}
這一段程式碼非常地簡單;首先,我先準備一個Read.TXT檔案,用來做讀取的動作,Read.TXT檔案的內容如下:
0123456789
9876543210
另外,也準備一個Write.TXT的檔案,用來當作寫入的動作。

程式碼主要分成三個部分,都是在做一樣的事─fseek()這個函式的用法。

1. 首先,用memset()把要儲存字串的位址szTemp做一個初始化的動作;

2. 用fseek()調整Position在檔案中的位置;

3. 連續用fread(), fwrite()把讀取出來的szTemp寫進Write.TXT中;

4. 為了要將字串秀在螢幕上,所以把szTemp最后一個字元置換成結束字元。

執行結果如下圖:


註解都已經加在程式碼之中了;如果不小心Google到這一篇文章的人,看不懂我在寫啥,那可能要麻煩你再多翻一下課本,畢竟這些函式的用法是寫給我自己看的!!....@@

從範例和復習的過程當中,fread(), fwrite()本身並沒有「結束字元 ('\0')」和「斷行 ('\n')」的觀念,所以必須靠fseek()來調整Position在檔案中的位置;而ftell()則是可以告訴設計師現在Position在檔案的哪裡。rewind()可以把Position直接移到檔案的最前面。

最后,再附上這些函式的原型宣告:

1. FILE *fopen(const char *path, const char *mode);

2. int fclose(FILE *stream);

3. size_t fread(void *ptr, size_t sz, size_t n, FILE *fp);

4. size_t fwrite(const void *ptr, size_t sz, size_t n, FILE *fp);

5. int fseek(FILE *fp, long offset, int origin);

6. long ftell(FILE *fp);

7. int rewind(FILE *fp);

沒有留言:

張貼留言