fwrite不写整个缓冲区

时间:2011-04-23 20:05:10

标签: c arrays file io buffer

我目前正在为简单的文件检查制作一个小型测试程序。程序将两个小矩阵(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,

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地址中的ram一样。

我的问题如下:为什么fwrite不将正确的数据写入文件。为什么它管理前14个元素而不是最后两个元素?当我编写和检索A和B的元素时,这与我之前对fwrite和fread的正确用法有何不同?

2 个答案:

答案 0 :(得分:4)

您正在编写二进制数据,因此您必须以二进制模式打开文件,默认为文本模式。这在Windows上有所不同,但不在* nix上,这解释了为什么它适用于其他人。

对于您的所有fopen来电,请在模式参数中加上字母'b',例如将“w +”替换为“w + b”,将“r”替换为“rb”,依此类推。

答案 1 :(得分:0)

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

如果printMatrix()输出最终换行符,结果看起来会更好。也许未终止的线路会对您的系统造成某种混淆?