Ich hoffe das ist was du gesucht hast (denn es hat mich ganz schön viel Zeit gekostet es du schreiben!):
Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_ENTRY_NAME 100
#define MAX_ENTRY_CONTENT 1024
void get_entry_error(int line, char *ptr, char *reason)
{
char near[6];
char *pos;
strncpy(near, ptr, sizeof(near) - 1);
if ((pos = strstr(near, "\n")))
*pos = 0;
printf("%d: syntax error near \"%s\" (%s)\n"
, line
, near
, reason);
exit(0);
}
char *get_entry(char *n, char *data)
{
/* buffers */
static char *name = 0;
static char *content = 0;
/* lengths */
int l_name = 0;
int l_content = 0;
/* "bool"s */
int is_content = 0;
int name_disabled = 0;
int content_disabled = 0;
/* current line */
int line = 1;
if (!name && !content)
{
name = (char *) malloc(MAX_ENTRY_NAME);
content = (char *) malloc(MAX_ENTRY_CONTENT);
if (!name || !content)
{
puts("out of memory");
exit(0);
}
}
memset(name, 0, MAX_ENTRY_NAME);
memset(content, 0, MAX_ENTRY_CONTENT);
while(*data)
{
switch(*data)
{
case '\n':
if (!is_content)
get_entry_error(line, data, "statement has no content");
/* is this the entry we were searching for? */
if (!strcmp(name, n)) return content;
memset(name, 0, MAX_ENTRY_NAME);
memset(content, 0, MAX_ENTRY_CONTENT);
is_content = 0;
name_disabled = 0;
content_disabled = 0;
l_name = 0;
l_content = 0;
line++;
break;
case ' ': case '\t':
if (is_content)
{
if (l_content)
content_disabled = 1;
}
else if (l_name)
{
name_disabled = 1;
}
break;
case ':':
if (is_content)
get_entry_error(line, data, "':' not allowed within this context");
is_content = 1;
name_disabled = 0;
break;
default:
if (name_disabled || content_disabled)
get_entry_error(line, data, "spaces are not allowed within names");
if (is_content)
{
if (l_content == MAX_ENTRY_CONTENT)
get_entry_error(line, data, "the content exceeds the buffer");
content[l_content++] = *data;
}
else
{
if (l_name == MAX_ENTRY_NAME)
get_entry_error(line, data, "the name exceeds the buffer");
name[l_name++] = *data;
}
}
data++;
}
return 0; /* nothing found */
}
int is_numeric(char *buffer)
{
if (buffer[0] == '-' && buffer[1] >= '0' && buffer[1] <= '9')
buffer++;
for(; *buffer >= '0' && *buffer <= '9'; buffer++);
return (*buffer == 0);
}
int main(void)
{
char cfg[] = "Auto : 100\n"
"Versicherung : 100\n"
"Miete : 200\n";
char *ptr;
int number;
if (!(ptr = get_entry("Auto", cfg)))
{
printf("entry not found\n");
}
else if (is_numeric(ptr))
{
number = atoi(ptr);
/* we really extracted the number...
as proof we do a simple calculation */
printf("content + 123 = %d\n", number + 123);
}
else
{
printf("entry is not a number\n");
}
return 0;
}
Ich habe mich mal an den "Coding-Standard" (http://www.free-hack.com/viewtopic.php?t=28480) gehalten und wenig kommentiert.
Wenn du etwas nicht verstehst frag einfach nur.
Zudem habe ich mich bemüt einige mögliche Fehler per Fehlermeldung auszugeben.
Solche Fehler sind zB: keinen Inhalt, also eine Zeile ohne ":", Lücken in Namen ("Aut o" --> Fehler), ":" im Inhaltsteil ("Auto: a:b" --> Fehler), ...
Außerdem werden Leerzeichen ignoriert ("Auto : 100" und " Auto : 100" sind das Selbe).
Der Code enthält auch ein Beispeil, also sollte die Benutzung klar sein.
Wenn nicht:
get_entry(n, b)
liefert einen Zeiger auf einen Zeichenvektor, der den Inhalt für das Element n im buffer b enthält.
Wenn n nicht in b gefunden werden kann, wird 0 zurückgegeben!
Damit n gefunden werden kann muss es in der Groß-/Keinschreibung mit dem in b befindlichen n übereinstimmen!
PS: der Puffer für den Rückgabewert der Funktion ist statisch um Speicher zu sparen, nach einem folgenden Aufruf:
ptr1 = get_entry("Auto", cfg);
ptr2 = get_entry("Miete", cfg);
entspricht ptr1 ebenfalls der Miete (da auf die selbe Speicherstelle gezeigt wird, also; ptr1 == ptr2 ist Wahr).
mfG. BlackBerry