データが 1 行であると仮定すると、非常に単純なコード例を次に示します。
明らかに、テストし、テストし、テストする必要があります。あなたの行動を見て、考えられるバグと私がするのを忘れていたことを修正し(今はあなたの仕事です)、あなたの新しい実装もそうです。
int main(void)
{
const char *key = "TEST";
const char *filename = "file";
char *val = get(filename, key);
if(val) {
printf("%s\n", val); // {. text .}
free(val); // don't to forget!
} else {
printf("'%s' was not found.\n", key);
}
}
char*
get(const char *filename, const char *key) {
char *line = NULL, *pline = NULL, *buf = NULL, *pbuf, *tbuf;
size_t size = -1, ssearch = strlen(key), i = 0, bufsize = 256;
int open = 0;
FILE *fp = fopen(filename, "r");
if(fp == NULL) {
fprintf(stderr, "Cannot read '%s' file.\n", filename);
exit(EXIT_FAILURE);
}
while(getline(&line, &size, fp) != -1) {
if(open == 0 && *line == '/' &&
strncmp(line + 1, key, ssearch) == 0 && isspace(((unsigned char)*(line + ssearch + 1)))) {
open = 1;
continue;
}
if(open) {
pline = line;
while(isspace((unsigned char) *pline)) ++ pline; /* strip white-spaces [\r\n\t\v ] */
if(*pline == '{') {
if((buf = malloc(bufsize)) == NULL) {
fprintf(stderr, "NO MEMORY!");
exit(EXIT_FAILURE);
}
++pline; /* strip '{' */
pbuf = buf;
while(1) {
if(*pline == '\0') {
fprintf(stderr, "EOF but '{' was not closed.");
exit(EXIT_FAILURE);
}
/* etc.. */
if(*pline == '}') break;
if((i + size + 1) >= bufsize) {
if((tbuf = realloc(buf, bufsize + size + 1)) == NULL) {
if(buf) free(buf);
fprintf(stderr, "No MEMORY!\n");
exit(EXIT_FAILURE);
}
buf = tbuf;
}
*pbuf ++= *pline++,
i ++;
}
*pbuf ++= '\0';
if(pline != NULL)
free(line);
fclose(fp);
return buf;
} else {
fprintf(stderr, "expected '{' but '%c' was found.\n", *pline);
exit(EXIT_FAILURE);
}
}
line = NULL;
size = -1;
}
if(line != NULL)
free(line);
fclose(fp);
return NULL;
}
更新:より単純なコードが書かれました。
#define EXPECTEDSYMBOL(w, f) \
fprintf(stderr, "expected '%c' but '%c' was found.\n", w, f); \
exit(EXIT_FAILURE)
char* get2(const char *filename, const char *key) {
char *line = NULL, *buf = NULL, *pline;
size_t size = -1, ssearch = strlen(key);
int open = 0;
FILE *fp = fopen(filename, "r");
if(fp == NULL) {
fprintf(stderr, "Cannot read '%s' file.\n", filename);
exit(EXIT_FAILURE);
}
while(getline(&line, &size, fp) != -1) {
if(open == 0 && *line == '/' &&
strncmp(line + 1, key, ssearch) == 0 && isspace(((unsigned char)*(line + ssearch + 1)))) {
open = 1;
continue;
}
if(open) {
pline = line;
while(isspace((unsigned char) *pline)) ++ pline;
if(*pline != '{') {
EXPECTEDSYMBOL('{', *pline);
}
if(strchr(pline, '}') == NULL) {
EXPECTEDSYMBOL('}', *(pline + strlen(pline) - 1));
}
buf = pline;
break;
}
line = NULL;
}
fclose(fp);
return buf;
}
これがお役に立てば幸いです。
編集#2:あなたの質問をもう一度読んだところ、以下のキーも必要であることがわかりました。
これを試して:
void
get(const char *filename, const char *key, char buf[][512]) {
char *line = NULL;
size_t size = -1, ssearch = strlen(key);
int open = 0;
FILE *fp = fopen(filename, "r");
if(fp == NULL) {
fprintf(stderr, "Cannot read '%s' file.\n", filename);
exit(EXIT_FAILURE);
}
while(getline(&line, &size, fp) != -1) {
if(open == 0 && *line == '/' &&
strncmp(line + 1, key, ssearch) == 0 && isspace(((unsigned char)*(line + ssearch + 1)))) {
open = 1;
continue;
}
if(open == 1) {
strcpy(buf[0], line);
++ open;
continue;
}
if((open + 1) == 3) {
getline(&line, &size, fp);
strcpy(buf[1], line);
break;
}
}
fclose(fp);
}
その後:
const char *key = "TEST"; // /TEST
const char *filename = "config";
char buf[2][512] = { { 0 } };
get(filename, key, buf);
printf("%s\n", buf[0]); // {. text . }
printf("%s\n", buf[1]); // {. infs .}