2013-11-24 97 views
0

我有一個函數loadsets()(加載設置的縮寫),它應該從名爲的文本文件加載設置Progsets.txt。 loadsets()在成功時返回0,在檢測到致命錯誤時返回-1。然而,實際上讀取的部分代碼Progsets.txt(三個fgets()),似乎都失敗並返回空指針,因此不會加載任何東西,而是一堆空值。我的代碼有問題嗎?當我運行代碼時,fp是一個有效的指針,我可以打開它閱讀。那麼,怎麼了?fgets()不從文本文件讀取?

此代碼用於使用cmd加載我非常基本的文本編輯器程序的默認文本顏色。

頭:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <Windows.h> 

#define ARR_SIZE 100 

struct FINSETS 
{ 
    char color[ARR_SIZE + 1]; 
    char title[ARR_SIZE + 1]; 
    char maxchars[ARR_SIZE + 1]; 
} SETTINGS; 

載入集():

int loadsets(int* pMAXCHARS) // load settings from a text file 
{ 
    FILE *fp = fopen("C:\\Typify\\Settings (do not modify)\\Progsets.txt", "r"); 
    char *color = (char*) malloc(sizeof(char*) * ARR_SIZE); 
    char *title = (char*) malloc(sizeof(char*) * ARR_SIZE); 
    char *maxchars = (char*) malloc(sizeof(char*) * ARR_SIZE); 
    char com1[ARR_SIZE + 1] = "color "; 
    char com2[ARR_SIZE + 1] = "title "; 
    int i = 0; 
    int j = 0; 
    int k = 0; 
    int found = 0; 

    while (k < ARR_SIZE + 1) // fill strings with '\0' 
    { 
     color[k] = title[k] = maxchars[k] = '\0'; 
     SETTINGS.color[k] = SETTINGS.maxchars[k] = SETTINGS.title[k] = '\0'; 
     k++; 
    } 

    if (!fp) // check for reading errors 
    { 
     fprintf(stderr, "Error: Unable to load settings. Make sure that Progsets.txt exists and has not been modified.\a\n\n"); 
     return -1; // fatal error 
    } 

    if (!size(fp)) // see if Progsets.txt is not a zero-byte file (it shouldn't be) 
    { 
     fprintf(stderr, "Error: Progsets.txt has been modified. Please copy the contents of Defsets.txt to Progsets.txt to manually reset to default settings.\a\n\n"); 

     free(color); 
     free(title); 
     free(maxchars); 

     return -1; // fatal error 
    } 

    // PROBLEMATIC CODE: 

    fgets(color, ARR_SIZE, fp);  // RETURNS NULL (INSTEAD OF READING FROM THE FILE) 
    fgets(title, ARR_SIZE, fp);  // RETURNS NULL (INSTEAD OF READING FROM THE FILE) 
    fgets(maxchars, ARR_SIZE, fp); // RETURNS NULL (INSTEAD OF READING FROM THE FILE) 

    // END OF PROBLEMATIC CODE: 

    system(strcat(com1, SETTINGS.color)); // set color of cmd 
    system(strcat(com2, SETTINGS.title)); // set title of cmd 
    *pMAXCHARS = atoi(SETTINGS.maxchars); 

    // cleanup 

    fclose(fp); 
    free(color); 
    free(title); 
    free(maxchars); 

    return 0; // success 
} 

Progsets.txt:

COLOR=$0a; 
TITLE=$Typify!; 
MAXCHARS=$10000; 

編輯:這裏是size()函數的定義。由於我只使用ASCII文本文件,因此我假設每個字符都是一個字節,並且可以通過計算字符數來計算文件大小(以字節爲單位)。任何可疑的東西?

大小():

int size(FILE* fp) 
{ 
    int size = 0; 
    int c; 

    while ((c = fgetc(fp)) != EOF) 
    { 
     size++; 
    } 

    return size; 
} 
+0

我的程序中沒有看到任何'fscanf'。 – haccks

+0

是的。在標題上錯字,抱歉。它應該是「fgets()不從文本文件讀取?」 – user3026735

+1

你的mallocing'char *'爲'char **',沒有檢查mallocs的返回值,並且在獲得大小後可能需要倒帶文件 – amdixon

回答

0

問題就出在你使用size()功能。它在文件句柄上反覆調用fgetc(),直到它到達文件末尾,遞增一個值以跟蹤文件中的字節數。

這不是一個壞方法(雖然我敢肯定有更好的,不涉及低效基於字符的I/O),但它確實有一個致命的缺陷你似乎都忽略了。

你叫後,您已經閱讀了文件中的所有方式來結束,這樣任何進一步的讀取,如:

fgets(color, ARR_SIZE, fp); 

只會失敗,因爲你在最後是已經的文件。在從size()返回之前,您可能需要考慮諸如rewind()之類的內容 - 這會將文件指針放回到文件的起始位置,以便您可以再次讀取它。