В момента правя малка тестова програма за проста проверка на файлове. Програмата записва две малки матрици (A и B) във файлове, затваря ги и ги отваря отново, чете матриците от файловете, умножава ги и записва получената матрица (C) в нов файл. След това затваря и отваря отново този файл, съдържащ отговора, и го отпечатва, за да проверя дали операцията IO е протекла правилно.
Проблемът ми е, че резултатната матрица се чете по различен начин от очакваното.
Смятам се за начинаещ в 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);
}
Което ми дава следния резултат:
A
1,2,3,1,
2,2,1,2,
4,2,3,1,
5,1,1,3,
B
3,2,1,4,
2,2,3,3,
4,1,3,2,
2,2,5,1,
C_буфер
21,11,21,17,
18,13,21,18,
30,17,24,29,
27,19,26,28,
Дължината на C файла е: 64
C_файл
21,11,21,17,
18,13,21,18,
30,17,24,29,
27,19,1,3,
Както можете да видите, последните два елемента в C_file са грешни, вместо това изходът показва последните два елемента в A, докато записвах съдържанието на файла в bufferA. Преминаването към буфер B ще размени последните два знака с последните елементи в B, което все още е погрешно. Копие на файл в друг проект ще даде последните две цели числа като каквото и да е в ram на този malloc адрес.
Въпросът ми е следният: Защо fwrite не записва правилните данни във файла. Защо управлява първите 14 елемента, но не и последните два? И как това се различава от предишните ми правилни употреби на fwrite и fread, когато написах и извлякох елементите на A и B?