Is there a best-practice on how to feed data to fwrite() when the input data is held in a 2-dimentional array and each column has to be saved into a separate file?
The example below simulates data read from a file ("buffer") which is processed and parsed into an 8 rows x 3 columns array ("processedData"). A loop follows to create a new file pointer for each column which is populated by reading one column at the time and saving each file. This results in 3 files of 8 bytes each.
Is there a more efficient way to feed columnar data to fwrite() instead of looping through the array contents one column at the time?
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
uint8_t t, p, s;
// Assume inputFile is a buffer with the contents of a file from disk
uint8_t buffer[24] = {2, 1, 3, 3, 2, 4, 4, 3, 5, 5, 4, 6, 6, 5, 7, 7, 6, 8, 8, 7, 9, 9, 8, 0};
uint8_t(*processedData)[8][3] = malloc(sizeof *processedData);
memset(processedData, '\0', sizeof(*processedData));
// Assume the contents of the buffer are processed in some way...
for (s = 0; s < 24; s++)
(*processedData)[s % 8][s % 3] = buffer[s];
// Parse the processed content by column and save in 3 separate files
for (t = 0; t < 3; t++)
{
uint8_t *hld = (uint8_t *)calloc(8, sizeof(uint8_t));
for (p = 0; p < 8; p++)
hld[p] = (*processedData)[p][t];
char *fileName = (char *)malloc(sizeof(char) * 30);
sprintf(fileName, "%s-%u", "TestFile", t);
FILE *tmpFile = fopen(fileName, "w+");
if (tmpFile == NULL)
{
fputs("File error", stderr);
exit(1);
}
fwrite(hld, 1, 8, tmpFile);
fclose(tmpFile);
free(hld);
}
return 0;
}
Your method can work, but is a bit cumbersome and has a few problems:
"wb".+in"w+"that allows reading from the file in addition to writing.hldarray.uint8_tfor loop index variables is error prone.s / 3instead ofs % 8for the row index.sprintfis not protected against buffer overflows: you should usesnprintf()instead.Regarding your question: Is there a more efficient way to feed columnar data to fwrite() instead of looping through the array contents one column at the time?
Since the columnar data is a not a contiguous set of bytes, you must iterate through the 2D array one way or another to collect the data for output. Note that there is no need to use
fwrite, you could just usefputcfor each byte directly, without the need for the intermediaryhldarray. Yet if the data elements are larger than a byte, or if your application is multithreaded, collecting the data in an array and using a singlefwriteis probably easier and more efficient. Just make sure the output file is open in binary mode.Here is a modified version:
Note also that
processedDatacould point directly tobufferand thus avoid the need for allocation and initialization: