C語言/C++讀取檔案資訊

blank__box發表於2016-11-09


(此圖來自王桂林課程系列)



函式fseek:

重定位流(資料流/檔案)上的檔案內部位置指標
注意:檔案指標指向檔案/流。位置指標指向檔案內部的位元組位置,隨著檔案的讀取會移動,
檔案指標如果不重新賦值將不會改變或指向別的檔案。
SEEK_SET: 檔案開頭
SEEK_CUR: 當前位置
SEEK_END: 檔案結尾
利用此函式可以指定讀取檔案中的第n個資料:fseek();先將指標移到需要讀取資料的
位置(比如說在學生資訊表中需要讀取第n個學生的資訊 fseek(fp,(long)(n*sizeof(Student)),0)從
第0個位置移動到第n個資訊的位置,再使用fread(&item,sizeof(Student),1,fp);就讀取到了相應的資料
Student item;
FILE *fp;
fp=open(..........);
fseek(fp,(long)(n*sizeof(Student)),0)
read(&item,sizeof(Student),1,fp);

fclose(fp);


C語言的檔案讀取相對麻煩     (SEEK_SET:檔案開始點) (SEEK_END:檔案末尾)   

第一種:先讀取檔案大小,通過檔案大小來定義動態陣列作為讀取檔案資訊的儲存空間,單個讀取字元

#include <iostream>
#include <stdlib.h>
#include <string.h>

using namespace std;

int main()
{
    long size;
    int i=0;
    FILE *fp;
    fp=fopen("D:\\Qt\\nicejob.txt","r+");
    fseek (fp, 0, SEEK_END);   //將檔案指標移動檔案結尾,但是這種用法通常是在二進位制檔案的處理中否則,容易發生混亂
    size=ftell (fp); //求出當前檔案指標距離檔案開始的位元組數
    cout<<size<<endl;
    fclose (fp);
    //前面先讀取到了檔案的大小  
    //我們可以通過獲得的size來開闢動態陣列讀取並存放檔案資訊並輸出

    fp=fopen("D:\\Qt\\nicejob.txt","r+");
        if(fp==NULL)
        {
            printf("error");
            return -1;
        }

    char *str;
    str=(char*)malloc(sizeof(char)*size);
    while(!feof(fp))//每次讀取一個字元
    {
        fscanf(fp,"%c",&str[i]);
        printf("%c",str[i]);
        i++;
    }
    fclose(fp);

}


一行一行的讀取字元

#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <vector>

using namespace std;

int main()
{
    FILE *fp=NULL;
    fp=fopen("D:\\Qt\\nicejob.txt","r+");
    if(fp==NULL)
    {
        printf("error");
        return -1;
    }

    int lineCount=0;
    char buf[1024];
    while(fgets(buf,1024,fp)!=NULL)//將資料讀取並存到buf中   一行一行的讀取
        lineCount++;
    rewind(fp);//這裡是將檔案位置指標從新置於檔案頭

    char **p=(char**)malloc((lineCount+1)*sizeof(char*));//定義一個指標陣列
    char **pt=p;

    while(fgets(buf,1024,fp)!=NULL)
    {
        int len = strlen(buf);
        *pt = (char*)malloc(len+1);
        strcpy(*pt,buf);//把讀取到的資料複製到pt陣列中
        pt++;
    }
    *pt=NULL;

    while(*p)
    {
        printf("%s",*p++);
    }
    fclose(fp);
    return 0;
}

C++方法:

通過定義向量來儲存資訊,相對來說簡潔了許多

#include <iostream>  
#include <stdlib.h>  
#include <string.h>  
#include <vector>  
  
using namespace std;  

int main()
{
    FILE *fp=fopen("D:\\Qt\\nicejob.txt","r+");
    if(fp==NULL)
    {
        return -1;
    }

    vector<string> vs;//生成string型別的變數vs
    char buf[1024];

    while(fgets(buf,1024,fp)!=NULL)//一行一行的讀取資訊
    {
        vs.push_back(buf);//將讀取到的資訊新增到buf的資訊結尾處
//        cout<<buf<<endl;
    }

    for(int i=0;i<vs.size();i++)
    {
        cout<<vs[i];
    }
    fclose(fp);
}



下面是檔案內的內容:

關於 feof 的問題 :

feof 這個函式,是去讀標誌位判斷檔案是否結束的。即在讀到檔案結尾的時候 再去讀一次,標誌位才會置位,此時再來作判斷檔案處理結束狀態,檔案到結尾。如果 用於列印,則會出現多打一次的的現象。

#include <stdio.h>
int main() {
    FILE* fp = fopen("text.txt","w+");
    if(fp == NULL)
        return -1;
    fputs("aaaaaaaaaaaaaaaaaaaaaaaaaaa\n",fp);
    fputs("bbbbbbbbbbbbbbbbbbbbbbbbbbb\n",fp);
    fputs("ccccccccccccccccccccccccccc\n",fp);
    fputs("ddddddddddddddddddddddddddd\n",fp);
    fputs("eeeeeeeeeeeeeeeeeeeeeeeeeee\n",fp);
    fputs("fffffffffffffffffffffffffff",fp);
    rewind(fp);
    char buf[30] = {0};
    while(fgets(buf,30,fp)&&!feof(fp))//最取最後一行的時候 feof 己經認為空了。
    { printf("%s",buf); } fclose(fp);//這樣的話就少讀了一行
    return 0;
}

如果最後一行,沒有行‘\n’的話則少讀一行。 Linux 中無論是gedit 還是vim 系統會自動在末行新增\n標誌。Windows當中要注 意系統不會自動新增\n,最好用返回值來判斷,是否讀到結尾。



寫入:

#include <iostream>

using namespace std;

int main()
{
    char *buf="abcdefg er\nsfsdf";
    FILE *fp=fopen("data.txt","w+");
    fprintf(fp,"%s",buf);
    fclose(fp);
    return 0;
}

讀取:

#include <stdio.h>
int main()
{
    FILE *fp = fopen("data.txt","r");
    if(fp == NULL)
    {
        printf("fopen error\n");
        return -1;
    }
    char buf[1024];
    while(fgets(buf,1024,fp) != NULL)
    {
        printf("%s",buf);
    }
    fclose(fp);
    return 0;
}




相關文章