2011-04-23 85 views
1

我目前正在做一個簡單的文件檢查的小測試程序。該程序將兩個小矩陣(A和B)寫入文件,關閉並重新打開它們,從文件中讀入矩陣,將它們相乘並將結果矩陣(C)寫入新文件。然後它關閉並重新打開包含答案的文件並將其打印出來以檢查IO操作是否正確進行。fwrite不寫整個緩衝區

我的問題是結果矩陣讀數與預期不同。

我認爲自己是C語言和文件輸入/輸出操作的初學者,這是導致我麻煩的代碼。我正在使用WinXP,Codeblocks和Mingw。

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

#define bufferA(i,k) (bufferA[i*cols+k]) 
#define bufferB(k,j) (bufferB[k*cols+j]) 
#define bufferC(i,j) (bufferC[i*cols+j]) 

void printMatrix(int *nMatrixToPrint, int nNumberOfElements, int nDimension) { 
// This function prints out the element of an Array. This array represents a matrix in memory. 

int nIndex; 
printf("\n"); 

for (nIndex = 0; nIndex < nNumberOfElements; nIndex++) { 
    if (nIndex % nDimension == 0) 
     printf("\n"); 
    printf("%d,",nMatrixToPrint[nIndex]); 
    } 

return; 
} 

int main(int argc, char *argv[]) { 
int nElements = 16, nDim = 4; 
int A[4][4] = {{1,2,3,1},{2,2,1,2},{4,2,3,1},{5,1,1,3}}; 
int B[4][4] = {{3,2,1,4},{2,2,3,3},{4,1,3,2},{2,2,5,1}}; 

// Create files of A and B, delete old ones if present 
FILE *fpA = fopen("A.dat", "w+"); 
FILE *fpB = fopen("B.dat", "w+"); 

// Write data to them 
fwrite((int*)A, sizeof(*A), nElements, fpA); 
fwrite((int*)B, sizeof(*B), nElements, fpB); 

// and close them 
fclose(fpA); 
fclose(fpB); 

// Reopen files 
fpA = fopen("A.dat", "r"); 
fpB = fopen("B.dat", "r"); 

// Allocate memory 
int *bufferA = (int*)malloc(nElements * sizeof(*bufferA)); 
int *bufferB = (int*)malloc(nElements * sizeof(*bufferB)); 
int *bufferC = (int*)calloc(nElements, sizeof(*bufferC)); 

// Read files 
fread(bufferA, sizeof(int), nElements, fpA); 
fread(bufferB, sizeof(int), nElements, fpB); 

printf("\nA"); 
printMatrix(bufferA, nElements, nDim); 
printf("\n\nB"); 
printMatrix(bufferB, nElements, nDim); 

// Matrix multiplication 
// Calculate and write to C 
int i,j,k = 0; // Loop indices 
int n = nDim,l = nDim, m = nDim, cols = nDim; 

// multiply 
for (i = 0; i < n; i++) {   // Columns 
    for (j = 0; j < m; j++) {  // Rows 
     //C(i,j) = 0; 
     for (k = 0; k < l; k++) { 
      bufferC(i,j) += bufferA(i,k) * bufferB(k,j); 
     } 
    } 
} 
printf("\n\nC_buffer"); 
printMatrix(bufferC, nElements, nDim); 

// Create C and write to it 
FILE* Cfile = fopen("C.dat", "w"); 
fwrite(bufferC, sizeof(*bufferC), nElements, Cfile); 

// Close files 
fclose(fpA); 
fclose(fpB); 
fclose(Cfile); 

// reopen C for reading 
Cfile = fopen("C.dat", "r"); 

// Obtain file size 
fseek(Cfile , 0 , SEEK_END); 
long lSize = ftell(Cfile); 
rewind(Cfile); 
printf("\nC file length is: %ld", lSize); 

// read data into bufferA 
fread(bufferA, sizeof(int), lSize, Cfile); 
fclose(Cfile); 

printf("\n\nC_file"); 
printMatrix(bufferA, nElements, nDim); 

// Free allocated memory and remove dangling pointers 
free(bufferA); bufferA = NULL; 
free(bufferB); bufferB = NULL; 
free(bufferC); bufferC = NULL; 

exit(0); 
} 

這給了我下面的輸出:

一個

1,2,3,1,
2,2,1,2,
4,2,3,1 ,
5,1,1,3,

3,2,1,4,
2,2,3,3,
4,1,3,2,
2,2,5,1,

C_buffer

21,11,21,17,
18 13,21,18,
30,17,24,29,
27,19,26,28,
C文件長度爲:64

C_FILE

21 ,11,21,17,
18,13,21,18,
30,17,24,29,
27,19,1,3,

正如你可以看到,最後兩個元素在C_file中是錯誤的,而輸出顯示A中的最後兩個元素,因爲我正在將文件內容寫入bufferA。切換到bufferB將交換最後兩個字符與B中的最後一個仍然錯誤的元素。將文件複製到另一個項目中將產生最後兩個整數,因爲無論在該malloc地址處的內存中。

我的問題如下:爲什麼不寫入適當的數據到文件中。它爲什麼要管理前14個元素,而不是後兩個?當我寫和檢索A和B的元素時,這與我之前正確使用fwrite和fread的方式有何不同?

+0

您對fread的電話不太正確;您將嘗試讀取64個值而不是16個值,因爲該文件的長度爲64個字節。您可能想要將相關參數切換到lSize/sizeof(int)。這應該不會導致問題,但 - 您是否嘗試過記錄fread的返回結果?它應該告訴你'項目'的數量(在這種情況下,整數,因爲你指定了sizeof(int))讀取。 – Tommy 2011-04-23 20:12:12

+0

謝謝湯米。我修復了fread調用並記錄了它的返回size_T,結果是14,這很奇怪,因爲磁盤上的文件是64字節,它是16個32位整數。 – Steinin 2011-04-23 20:30:37

+0

對不起兄弟,你的代碼在我的Ubuntu盒子上工作正常。 – karlphillip 2011-04-23 20:56:47

回答

4

您正在編寫二進制數據,因此您必須以二進制模式打開文件,默認爲文本模式。這在窗口上有所不同,但不在* nix上,這就解釋了爲什麼它適用於這裏的其他人。

對於您所有的fopen調用,在模式參數中包括字母'b',例如,用「w + b」替換「w +」,用「rb」替換「r」等等。

+0

這確實是個問題。謝謝。 – Steinin 2011-04-23 21:31:24

+0

我以前經歷過這種情況,但現在我遇到了與「rb」選項相同的問題事件。我告訴fwrite寫239616整數,但它只寫了3072,有時只寫1024,有時寫2048,它改變了。問題是什麼? – 2017-11-14 04:46:20

+0

哦,我發現當緩衝區指針錯誤時,可能會發生這種情況。我應該給fwrite(&buff [0],sizeof(int),count,fp);但我給了fwrite(&buff,sizeof(int),count,fp);因爲失誤。 – 2017-11-14 04:54:20

0

你的程序在我的Mac上運行得很好。

如果printMatrix()輸出最終換行符,結果會更好。也許未終結的行會在你的系統上造成某種混亂?