Moin!
Ist die Zielumgebung ein µC?
Zitat :
|
| in einem Vektor abgelegt, der eine struct aus den flags, ein paar int-Werten sowie auch einen Bezeichnungstext enthält. |
Also so:
struct Eigenschaft
{
int nummern;
int flags;
char bezeichner[maximale_String_Länge];
} Eigenschaften[Anzahl_der_Elemente];
?
Zitat :
|
| Um Probleme durch Eingabe zu langer Texte zu vermeiden, wollt ich die Eingaben aus einer Initalisierungs-Variablen ala char[] Name = "Bla1" in die Elemente kopieren und bei zu langen bezeichnungen ggf. nach X Zeichen das Kopieren Abbrechen und \n dranhängen, um eine definierte maximale Bezeichnungslänge zu haben. |
Das erledigt man dann in so einer Art Konstruktor,m der den Vektor mit allen Werten initialisiert.
Nachteil dabei ist allerdings, dass die Werte im RAM zweimal vorliegen, nämlich einmal im Vektor aller Elemente sowie aus den rein statischen Zellen, die den Initialisierungstext enthalten.
Das ist nachteilig, man kann auch im Vektor bloß Zeiger auf die jeweiligen, statischen!, Texte ablegen:
...
char* bezeichner;
...
Im "Konstruktor" initialisiert richtet man die Zeiger dann auf die entsprechenden Strings, ohne kopieren zu müssen.
Gehen wir aber mal davon aus, dass die Strings im Vektor abgelegt werden, wobei der Bezeichner STRING_LÄNGE Zeichen enthalten darf, dann kann das so aussehen:
Header:
/* Alle Texte als kommaseparierte Liste: */
#define TEXTE "Text1", "Text2", "Text3", "..."
/* und maximale Stringlänge: */
#define TEXT_LÄNGE 4
Programmkode:
/* statisches Array mit den Texten: */
static char* stat_texte[] = {TEXTE};
/* Anzahl der Elemente (kann im Präprozessor berechnet werden): */
#define TEXT_ANZAHL (sizeof stat_texte/sizeof(char*))
/* Struktur (davon ein Vektor mit gleicher Anzahl an Elementen wie es Texte gibt): */
static struct Eigenschaft
{
int nummern;
int flags;
char bezeichner[TEXT_LÄNGE+1];
} Eigenschaften[TEXT_ANZAHL];
/* Struktur initialisieren: */
static void _ctor(void)
{
register unsigned char i;
for(i=0;i<TEXT_ANZAHL;i++)
{
strncpy(Eigenschaften[i].bezeichner, stat_texte[i], TEXT_LÄNGE);
Eigenschaften[i].bezeichner[TEXT_LÄNGE] = '\0';
}
}
So könnte das aussehen.
Es werden auf jeden Fall nur soviele Bytes kopiert, wie Platz vorhanden ist. Dann wird mit einem NUL, also Null-Byte, terminiert. \n ist ein Zeilenumbruch und terminiert den String nicht.
Das einzige, was benötigt wird, sind die diversen Bezeichner (Texte), der Rest erledigt sich automatisch. Das einzige, was im Programm noch erledigt werden muss, ist, den Vektor zu initialisieren (_ctor).
Nachteile sind aber weiterhin:
1. Die Strings sind eigentlich doppelt vorhanden und überlange Texte verbrauchen auf jeden Fall unnötig Speicherplatz. Mit dem Präprozessor kommt man nicht groß weiter, denn Zuweisungen wie
static char text[5] = "Hallogggggg";
Werden ganz brav (gibt beim GCC ne Warnung) umgesetzt: Fünf Bytes (die ersten) werden im Array abgelegt, es fehlt aber die Terminierung! Absolut tödlich, wenn man mit reinen C-Strings arbeitet.
Arbeitet man jedoch mit Zeigern im Vektor, werden die Strings bei statischer Zuweisung nur einmal im RAM abgelegt, dafür fehlt entweder die Terminierung (String zu lang) oder aber man kann sie nicht in der Länge beschänken.
Wird das ganze auf AVRs umgesetzt, empfiehlt es sich außerdem, die konstanten Strings im ROM abzulegen. Der Datentyp heißt dann prog_char* und pgmspace.h muss inkludiert werden.
Edit:
Man kann _ctor sogar so mit Attributen versehen, dass der Konstruktor automatisch ausgeführt wird, also im "Konstuktorsegment" landet. Ergibt nur dann Sinn, wenn es eine argumentlose Prozedur ist.
P.S.: sollen die Bezeichner zur Laufzeit verändert werden können? Wenn nein, dann würde ich das wirklich statisch machen (auf Kosten einer nicht festgelegten Stringlänge).
_________________
[ Diese Nachricht wurde geändert von: DonComi am 2 Okt 2010 2:02 ]