HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

fprintf for heterogeneous struct

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
structfprintfheterogeneousfor

Problem

Is there a simple way to concatenate all of the fprintf(qFile, "%-1.1c", mod[cnt].name[x]); expressions into a small number of expressions?

Appreciate any other suggestions.

#include "stdafx.h"
    #include 
    #include 

    // fprintfQuestion.cpp : Defines the entry point for the console application.
    // add _CRT_SECURE_NO_DEPRECATE  to Properties \ C\C++ \ Preprocessor \  Preprocessor Definitions

    struct mod
    {
        char    name[32];
        int     dateStart;
        int     dateEnd;
    };


The struct mod is an abbreviated version of the struct used in a GUI editor for the game for which I'm an apprentice developer. The full struct includes about 20 variables. Objects from this struct correspond to "script modules" used by the game's computer-opponent, and which can be randomly or statically assigned to specific scenarios in the game by scenario designers.

The goal of the exercise I'm engaged in at present is to develop a "loader" application that can transfer data between the .dat files the editor works with and .csv files that humans can manipulate in spreadsheets. Most of the scenario designers are not programmers.

```
int main()
{
FILE pFile, qFile;
int cnt = 0, n = 0;
char str[40]; //1328
mod mod[3]; //2000
long bytes = 1328; // first record of 0 to 1327 is blank

pFile = fopen("W:\\User\\dir\\sourcefile.dat", "rb");
qFile = fopen("W:\\User\\dir\\targetfile.csv", "a");

for (cnt = 0; cnt < 3; cnt++)
{
fseek(pFile, bytes, SEEK_SET);
for (n = 0; n < 40; n++)
{
str[n] = getc(pFile);
};
memmove(mod+cnt, str, 40);
fprintf(qFile, "%-1.1c", mod[cnt].name[0]);
fprintf(qFile, "%-1.1c", mod[cnt].name[1]);
fprintf(qFile, "%-1.1c", mod[cnt].name[2]);
fprintf(qFile, "%-1.1c", mod[cnt].name[3]);
fprintf(qFile, "%-1.1c", mod[cnt].name[4]);

Solution

Merge all fprintf()s into a single one

You could try merging all of your fprintf() calls into this single call:

fprintf(qFile, "%.32s,%.6i,%.6i,\n", mod[cnt].name, mod[cnt].dateStart,
        mod[cnt].dateEnd);


The %.32s specifier means "print a string up to 32 characters long". From the example output you showed in the comments, I think that this would work for you. If you don't need a trailing comma at the end of the line, you could remove it. (Your code had it there but your example didn't so I left it in).
Use fread()

Instead of this loop and memmove():

for (n = 0; n < 40; n++)
         {
           str[n] = getc(pFile);
         };
    memmove(mod+cnt, str, 40);


You could use one call to fread:

fread(&mod[cnt], 1, sizeof(mod[cnt]), pFile);


You might want to static_assert that sizeof(struct mod) == 40 somewhere, since your code seems to depend on that.

Code Snippets

fprintf(qFile, "%.32s,%.6i,%.6i,\n", mod[cnt].name, mod[cnt].dateStart,
        mod[cnt].dateEnd);
for (n = 0; n < 40; n++)
         {
           str[n] = getc(pFile);
         };
    memmove(mod+cnt, str, 40);
fread(&mod[cnt], 1, sizeof(mod[cnt]), pFile);

Context

StackExchange Code Review Q#156146, answer score: 4

Revisions (0)

No revisions yet.