我目前正在做一个简单的文件检查的小测试程序。该程序将两个小矩阵(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("nnB");
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("nnC_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("nnC_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日,
29日,30日,17日,24日
26日,27日,19日,28日,
C文件长度为:64
C_file
21日,11日,21日,17日,
18日,13日,21日,18日,
29日,30日,17日,24日
27日,19日,1,3,
如您所见,C_file中的最后两个元素是错误的,相反,当我将文件内容写入bufferA时,输出显示了A中的最后两个元素。切换到bufferB会将B中的最后两个字符与最后一个元素交换,这仍然是错误的。将文件复制到另一个项目将产生最后两个整数,作为该malloc地址ram中的任何内容。
我的问题如下:为什么fwrite不把适当的数据写入文件?为什么它可以管理前14个元素,而不能管理后两个元素?当我写和检索A和B的元素时,这与我以前正确使用fwrite和read有什么不同?
您正在写入二进制数据,因此您必须以二进制模式打开文件,默认是文本模式。这在windows上有区别,但在*nix上没有,这就解释了为什么它对这里的其他人有效。
对于所有的fopen调用,在mode参数中包括字母'b',例如将"w+"替换为"w+b",将"r"替换为"rb"等等。
你的程序在我的Mac上运行得很好。
如果printMatrix()输出最后的换行符,结果看起来会更好。也许未终止的线路在您的系统上引起了某种混乱?