scanf和fscanf讀取文件

這篇是針對推箱子游戲而寫的,某個時候在學C語言,最近轉到windows設計,不知道是否有一樣的感覺,後面的東西學了,前面的就有點生疏了。其實,個人理解是,注意力轉移了,當集中於當前問題的時候就會忽略之前的某些知識。這也說明,人的注意力是隨着時間,學習內容的不一樣在起變化。可是,只要稍微複習一下就能很快恢復。windows

問題:好比一個文本文件的內容以下:數組

[1]
0000000000000000
0000000000000000
0000000000000000
0000011100000000
0000013100000000
0000012111100000
0001114243100000
0001324611100000
0001111410000000
0000001310000000
0000001110000000
0000000000000000
0000000000000000
0000000000000000
[2]
0000000000000000
0000000000000000
0001111100000000
0001622100000000
0001244101110000
0001242101310000
..................(截選)函數

[]內是序號,往下延伸,每一個[]下面是14行16列的數據,我想獲取給定的某個序號下面的這個二維數組數據,好比說,序號[10]下面的14*16列的數據。學習

————————————————————————————————————————————————————————————spa

在這個問題以前,首先理解一下流的概念,簡易記錄一下:設計

流有不少種,包括輸入流,輸出流等,這裏只說輸入流,好比stdin,在調用scanf函數讀取這個流的時候,有幾個須要注意的要點:
首先,scanf忽略前面的空格,回車等等字符
其次,在讀取的時候,流中還有一個指針在不停的移動,也就是遊標。作個圖來講明:
指針

想輸入一個數據ABCD到字符串中,在開始的時候,故意敲入空格+回車鍵,這對scanf無影響,它會忽略,一直讀取ABCD,又遇到一個回車,遊標最終停留在回車這個字符上。code

這個回車鍵被scanf獲取了嗎?實際上是沒有的,好比接下來能夠用c=getchar(),就能夠捕捉到這個回車字符。blog

同理,將stdin換成文件fp,同樣遵循這個規則。由於不是專項整理流的問題,因此只簡單歸納到這。遊戲

————————————————————————————————————————————————————————

對於上題的解法是,從fp中讀取一個字符串,而後和待匹配的序號比較,好比和字符串"[10]"比較,若是相等,則遊標就定位在[10]以後的位置。

觀察上面的文本文件,每一行以後就是一個回車,因此每次從fp中讀取一個串,要麼讀的是[xx],要麼讀的就是二維數組的一行數據,固然,這個串的存儲長度也至少大於一行的數據,至少爲16個。

具體

首先獲取要取的序號,定義一個字符串,將之寫入其中。

char str[10];
sprintf(str,"[%d]",n);

接着,按串讀取fp,與之相比較。

    FILE *fp=fopen("map.txt","rb");  //打開文本文件
    if(fp==NULL)
        return;
    char data[20];
    fscanf(fp,"%s",data);//先讀入一個串
    while(strncmp(str,data,strlen(str))!=0)//相等返回0
    {    
        if(fscanf(fp,"%s",data)==NULL)//循環讀取,遊標也在移動
            break;        
    }

假如讀取到[10],符合題意了,則遊標就正停留在[10]的後面,下面就是[10]序號下的14*16的數據。這個地方還有一個用處,好比說,一共有40關,假如玩家通關了,再掃描文件確定找不到[41]的序號,就能夠斷定玩家通關了。

由於要讀取14*16,至關於二維數組,處理以下:

    for(int y=0;y<14;y++) //
    {
        fscanf(fp,"%s",data);//讀取一行
        for(int x=0;x<16;x++)//
        {
            map[y][x]=data[x]-'0';//字符變整型,填充map[][],map[][]是一個整型的二維數組,因此須要轉換
            ......
        }
    }

這樣,問題就解決了。

完整的示例代碼

void LoadMap(int n) //載入地圖,主要負責填充map[][]的二維數組,map[][]是操縱畫圖的關鍵
{
    char str[10];
    sprintf(str,"[%d]",n);
    FILE *fp=fopen("map.txt","rb");  //打開文件,讀取地圖數據,所謂地圖,就是用數字來(標示)操縱位圖塊
    if(fp==NULL)
        return;
    char data[20];
    fscanf(fp,"%s",data);//先讀入一個串
    while(strncmp(str,data,strlen(str))!=0)//相等返回0
    {    
        if(fscanf(fp,"%s",data)==NULL)//循環讀取,遊標也在移動
            break;        
    }
    for(int y=0;y<14;y++) //行
    {
        fscanf(fp,"%s",data);//讀取14行
        for(int x=0;x<16;x++)//列
        {
            map[y][x]=data[x]-'0';//字符變整型,填充map[][]
            if(map[y][x]==MANATROAD||map[y][x]==MANATDESTINATION)
            {
                manposition.x=x;//人的位置
                manposition.y=y;
            }
        }
    }
    fclose(fp);
}

*注:這段程序,每次都要掃描整個文件,獲取與序號相同的串,因爲文件比較小,影響也不是太大。

總結:對一個文本文件的搜索過程。

相關文章
相關標籤/搜索