Suppose one has an array of strings:
const char str1[] = "some/path";
const char str2[] = "another/path";
const char str3[] = "and/a/third/path";
const char* strs[3];
strs[0] = str1;
strs[1] = str2;
strs[2] = str3;
Retaining the original definitions of the strings (i.e., str1
, str2
, and str3
), I would like to be able to modify the paths in the array by one character under control of a preprocessor directive. The simplest way I have found to do this requires dropping the const
qualifier, addition of a superfluous null byte, and shifting each element to the right.
char str1[] = "some/path\0";
char str2[] = "another/path\0";
char str3[] = "and/a/third/path\0";
char* strs[3];
strs[0] = str1;
strs[1] = str2;
strs[2] = str3;
#ifdef build_option
for(int i=0; i<3; i++) {
for(int j=strlen(strs[i]); j>=0; j--) {
strs[i][j] = strs[i][j-1];
}
strs[i][0] = '.'; // prepend each path with this character
}
#endif
fprintf(stdout, "%s\n%s\n%s\n", strs[0], strs[1], strs[2]);
Output:
.some/path
.another/path
.and/a/third/path
This works well enough, but I wonder if there is a simpler or more idiomatic way of doing the same thing, preferably statically (though it doesn't have to be).
Edits:
To clarify the scenario, only the original string is needed in the primary compilation route; in a lesser used, alternate compilation route, both the original and modified strings are required. In the latter route, the modified form is the primary one, serving the same role as the original throughout the program (however, access to the original is still needed).
Thanks to all for the many great suggestions; a combination of them were used to arrive at the following:
#include <stdio.h>
//#define build_option // rare compilation route
#ifdef build_option
#define STR_OFFSET 0
#else
#define STR_OFFSET 1
#endif
int
main(int argc, char *argv[])
{
const char str1[] = ".some/path";
const char str2[] = ".another/path";
const char str3[] = ".and/a/third/path";
const char* strs[3] = { str1,
str2,
str3 };
for(int i=0; i<3; i++)
fprintf(stdout, "%s\n",strs[i]+STR_OFFSET);
#ifdef build_option
fprintf(stdout, "\noriginal:\n");
for(int i=0; i<3; i++)
fprintf(stdout, "%s\n",strs[i]+1);
#endif
return 0;
}
Without build_option
defined, this gives
some/path
another/path
and/a/third/path
With build_option
defined, this gives
.some/path
.another/path
.and/a/third/path
original:
some/path
another/path
and/a/third/path