jetbomber117
jetbomber117

Reputation: 79

#define a char array without null termination in C++

I am working on a industry safety product that requires very fast startup time. I am trying to follow an industry standard for outputting an ASCII file. In order to speed up this file formatting step, I have used #define's to create several character arrays in static memory. Here's a small section for example:

#define COMTRADE_STATION_ID         "Station Name,Device ID,1999\r\n"
#define COMTRADE_CHANNEL_COUNT      "10,10A,0D\r\n"
#define COMTRADE_FREQUENCY          "60\r\n"
#define COMTRADE_FILE_TYPE          "BINARY\r\n1\r\n"

struct TS_ComtradeConfig
{
    const char StationID[sizeof(COMTRADE_STATION_ID)];
    const char ChannelCount[sizeof(COMTRADE_CHANNEL_COUNT)];
    char Frequency[sizeof(COMTRADE_FREQUENCY)];
    const char FileType[sizeof(COMTRADE_FILE_TYPE)];
};

TS_ComtradeConfig ConfigFile =
{
        {COMTRADE_STATION_ID},
        {COMTRADE_CHANNEL_COUNT},
        {COMTRADE_FREQUENCY},
        {COMTRADE_FILE_TYPE}
};

And here's some basic code I've been using for printing it out.

for(int nIndex = 0; nIndex < sizeof(ConfigFile); nIndex++)
{
    printf("%c", ((char*)(ConfigFile.StationID))[nIndex]);
}

This works fine for generating the static char arrays, and it works fine for printing out the entire ConfigFile as a whole, but the char arrays are null-terminated, which means the end result does not meet the industry standard. It seems that the #define strings are being null-terminated by the pre-processor. Is there any way around this? Or any other methods for doing this sort of high speed operation?

Upvotes: 0

Views: 785

Answers (2)

Peter - Reinstate Monica
Peter - Reinstate Monica

Reputation: 16017

How about string concatenation:

#define COMTRADE_STATION_ID         "Station Name,Device ID,1999\r\n"
#define COMTRADE_CHANNEL_COUNT      "10,10A,0D\r\n"
#define COMTRADE_FREQUENCY          "60\r\n"
#define COMTRADE_FILE_TYPE          "BINARY\r\n1\r\n"

#define COMTRADE_ALL COMTRADE_STATION_ID COMTRADE_CHANNEL_COUNT COMTRADE_FREQUENCY COMTRADE_FILE_TYPE

    // no struct, plain char array, no intervening nulls (but a trailing one)
char[sizeof(COMTRADE_ALL)] comTradeAll = COMTRADE_ALL; 

Upvotes: 3

Cornstalks
Cornstalks

Reputation: 38217

for(int nIndex = 0; nIndex < sizeof(ConfigFile); nIndex++)
{
    printf("%c", ((char*)(ConfigFile.StationID))[nIndex]);
} 

I have no idea why you're printing it out like that, char by char. If there's padding in that struct, you're in for some trouble.

Why not just iterate through the members of ConfigFile and fwrite them? Replace the whole loop with:

// Add a -1 to the size to skip the \0
fwrite(ConfigFile.StationID, sizeof(ConfigFile.StationID) - 1, 1, stdout);
fwrite(ConfigFile.ChannelCount, sizeof(ConfigFile.ChannelCount) - 1, 1, stdout);
fwrite(ConfigFile.Frequency, sizeof(ConfigFile.Frequency) - 1, 1, stdout);
fwrite(ConfigFile.FileType, sizeof(ConfigFile.FileType) - , 1, stdout);

Not only is the code more clear (since you aren't doing your weird char pointer hack), it prints out exactly what you want. It also might be slightly more efficient, as you don't have a formatting string to process (it just does a data dump).

Upvotes: 2

Related Questions