I have a number of very long arrays. No run-time sort is possible. It is also time consuming to sort them manually. Moreover, new elements can be added in any order later, so I would like to sort them by value using C preprocessor or maybe there is any compilers flag (GCC)?
For example:
sometype S[] = {
{somevals, "BOB", someothervals},
{somevals, "ALICE", someothervals},
{somevals, "TIM", someothervals},
}
must be sorted so:
sometype S[] = {
{somevals, "ALICE", someothervals},
{somevals, "BOB", someothervals},
{somevals, "TIM", someothervals},
}
SOLVED
Ok, here is my solution:
- Manually copy&paste each array into a temporary file called tobesorted.c
- Sort it by 2nd column:
sort -b -i --key=2 tobesorted.c
- Copy&paste output back into original file.
Actually, it would be nice to开发者_如何学C have some possibility to call "sort" directly from the preprocessor (I had a hope that at least GCC somehow support such features, but it seems that it doesn't).
Do this.
Put your giant array in a file.
Sort the file with the built-in
sort
Write a small program to create C code from the file. A C program that writes C programs is fine. You can use Python and some of it's cool template packages to make this job simpler.
Compile the remaining program consisting of the sorted file transformed into C code plus the rest of your program.
No, it is not possible. You cannot do string operations (other than concatenation) with the preprocessor. And you can't compare strings with template metaprograming, either.
[edit] What you could do is put your datastructure in a file that is meant to be preprocessed by an external build script (e.g. the unix "sort" utility), and then modify your makefile/project so that at build time, you generate a C file with the (sorted) initialized arrays
I don't think you can do it in the gcc preprocessor, never seen something that could do what you are looking for.
But you could write your own "preprocessor" in your favourite scripting language (python, perl, sed etc...) that would sort those values before gcc kicks in.
I can think of no possibility to use the preprocessor, but you can use a combination of sort
and #include
to achieve the desired effect:
Put just the values into a seperate file values.h
with the sort key being in front (you will need to rearrange your struct sometype
for this):
{"BOB", somevals, someothervals},
{"ALICE", somevals, someothervals},
{"TIM", somevals, someothervals},
In your Makefile, use the Unix command sort
to sort that file into values_sorted.h
:
sort < values.h > values_sorted.h
In your actual code, include the sorted file:
sometype S[] = {
#include "values_sorted.h"
};
The following worked for two and three elements:
// Experiment: static sort:
#define STATIC_SORT2(CMP, a, b) CMP(a,b) <= 0 ?(a):(b), CMP(a,b) <= 0 ? (b):(a),
#define STATIC_SORT3(CMP, a, b, c) \
(CMP(a,b) <= 0 && CMP(a,c) <= 0 ? (a) : \
CMP(b,a) <= 0 && CMP(b,c) <= 0 ? (b) : \
(c)), \
(CMP(a,b) <= 0 && CMP(a,c) <= 0 ? ( CMP(b,c) <= 0 ? (b) : (c) ) : \
CMP(b,a) <= 0 && CMP(b,c) <= 0 ? ( CMP(a,c) <= 0 ? (a) : (c) ) : \
(CMP(a,b) <= 0 ? (a) : (b))), \
(CMP(a,c) <= 0 && CMP(b,c) <= 0 ? (c) : \
CMP(a,b) <= 0 && CMP(c,b) <= 0 ? (b) : \
(a))
// Example:
// #define STATIC_INT_CMP(a,b) ((int)(a) - (int)(b))
// int sorted[] = { STATIC_SORT3(STATIC_INT_CMP, 2, 3, 1 } // gives { 1, 2, 3 }
// #define STATIC_INT_COCMP(a,b) ((int)(b) - (int)(a))
// int cosorted[] = { STATIC_SORT3(STATIC_INT_COCMP, 2, 3, 1 } // gives { 3, 2, 1 }
But I'd say that it is clear that this approach does not generalize to arbitrary sized arrays. I suppose it is not possible, but I still don't have a formal proof for this conjecture.
精彩评论