2012-02-20 69 views
-1

我有這個防禦性編程問題,我不知道如何解決。驗證輸入文件的內容

我有這個功能,需要文件路徑和表的大小(行/列數)作爲參數,我正在尋找更好的方式來驗證輸入文件。我假設這個函數的參數總是正確的。 size表示存儲在文件中的表的 「小面」:

例如:

1 2 3 4 
5 6 7 8 

大小= 2 是正確的而

1 2 3 4 5 
5 6 7 8 9 

大小= 2 是不正確我想也可以拒絕這樣的文件

1 2 3 4 5 6 7 8 

尺寸= 2(其通過的fscanf接受)

我想能夠拒絕文件的另一種類型是

1 2 3 
4 5 6 

大小= 2

至於現在我唯一的安全措施是檢查文件的元素是否真的是數字。

下面是代碼我迄今所做的:

void import(float** table, int size, char* path) 
{ 
    FILE* data = fopen(path, "r"); 
    assert(data); 
    int i,j; 
    int st; 

    for (i=0; i<size; i++) 
    { 
     for(j=0; j<(size*2)-1; j++) 
     { 
      st = fscanf(data, "%f", &table[i][j]); 
      if (!st) 
      { 
       printf("Error while importing the file.\n"); 
       fclose(data); 
       return -1; 
      } 
     } 
    } 
    fclose(data); 
} 

我真的不何處以及如何開始,我不是在C真正精通,大家似乎都存在很多功能和機制去做我想做的事情,但它們看起來都非常複雜,有些實際上比我提供的代碼更長。

如果任何人都可以指出我的方向會很棒。

+0

是什麼* 「號= 2」 *是什麼意思? – LihO 2012-02-20 21:15:38

+1

我不認爲我理解一個正確的文件是什麼樣子。我只能看到'2'總是對的。 – cnicutar 2012-02-20 21:15:52

+0

@LihO輸入數字,代碼中的大小 – Sword22 2012-02-20 21:16:23

回答

1

您的循環可能看起來像這樣:

char line[1000], *token; 
for (i = 0; i < size; i++) // for each line 
{ 
    if (fgets(line, 1000, data) != NULL) // read line 
    { 
     token = strtok (line," "); 
     for (j = 0; j < (size * 2) - 1; j++) // for each number from line 
     { 
      if (sscanf(token, "%f", &table[i][j]) <= 0) 
      { 
       // there are columns missing: 
       printf("Error while importing the file.\n"); 
       fclose(data); 
       return -1; 
      } 
      token = strtok (NULL," "); 
     } 
    } 
    else 
    { 
     // there are rows missing: 
     printf("Error while importing the file.\n"); 
     fclose(data); 
     return -1; 
    } 
} 

還要注意的是assert(data);應該這樣被替換:

if (!data) 
{ 
    printf("Error while openning the file [filePath=\"%s\"].\n", filePath); 
    cleanExit(); 
} 
+0

@ Sword22:對不起,我在那裏發生錯誤。你不能直接從'line'讀取這個輸入,你必須把它分成標記。現在檢查我的答案。 – LihO 2012-02-20 23:16:50

1

您無法輕易檢測到scanf()中的行的末尾,因此直接使用該行並不符合您的標準。

您可能需要閱讀整行(fgets()或可能是getline()),然後依次處理每一行。行處理可以使用sscanf(),您也可以使用%n指令。總的來說,這歸結爲:

for (line_num = 0; line_num < size; line_num++) 
{ 
    ...read line from file into buffer line, checking for EOF... 
    start = line; 
    for (i = 0; i < 2 * size; i++) 
    { 
     if (sscanf(start, "%f%n", &value, &offset) != 1) 
      ...ooops - short line or non-numeric data... 
     else 
     { 
      start += offset; 
      table[line_num][i] = value; 
     } 
    } 
} 
...check that there's no clutter after the last expected line... 
0

你也可以計算整個文件的校驗和。問題是你對此有多認真。創建xor校驗和很容易,但對於碰撞並不是很安全。最好的可能是使用類似sha-1的東西,如果它很重要的話。