我以这种格式输入一个char数组:"key = value\0key = value...\0"
(最后一对以2个NUL终结符结束 - 其中一对+整个字符串一个
我想将它分成{key,value}对,以便打印出来。
这是我的方法,有更好的方法吗?
char str [] = "line 1 = But I set fire to the rain\0line 2 = Watched it pour as I touched your face\0line 3 = Well, it burned while I cried\0line 4 = 'Cause I heard it screaming out your name, your name!\0";
char * p = str;
char key[10], value[128], * delimiter;
while(*p){
memset(key, 0, sizeof(key));
memset(value, 0, sizeof(value));
delimiter = strchr(p, '=');
strncpy(key, p, delimiter - p);
// not sure where the NUL terminator is, so use strcpy
strcpy(value, 1 + delimiter);
printf("key: %s\n value: %s\n", key, value);
p += strlen(p) + 1;
}
答案 0 :(得分:2)
有几个选项可供选择,具体取决于您是否需要NUL
- 终止字符串以及您的缓冲区是否为只读。
如果您只想打印组合字符串的连续元素,则可以直接将其用作缓冲区:
char str[] = ...;
char *key, *val;
for(key = str; *key; key += strlen(key) + 1) {
val = strchr(key, '=') + 1;
printf("%.*s = %s", val - key - 1, key, val);
}
使用%.*s
告诉printf
从字符串中打印动态数量的字符。
如果你想要更高级的东西,你可能会使用两遍法。第一遍将计算键值对的数量,而第二遍将保留指针,长度,副本或您想要的任何其他信息。这种方法还需要比原始方法更多的清理。
要获得对的数量,您可以执行以下操作:
char str[] = ...;
char *p;
int count;
for(p = str, count = 0; *(p = strchr(p, '\0') + 1); count++) ;
如果您可以使用指向原始缓冲区中的键和值的指针(以及键的长度),则只需要分配count
对指针和长度:
char *keys, *vals;
int i, *klens;
keys = malloc(count * sizeof(char *));
vals = malloc(count * sizeof(char *));
klens = malloc(count * sizeof(int));
if(keys == NULL || vals == NULL || klens == NULL) {
goto cleanup;
}
for(i = 0, p = str; i < count; i++) {
keys[i] = p;
vals[i] = strchr(p, '=') + 2;
klens[i] = vals[i] - keys[i] - 3;
p = strchr(vals[i], '\0') + 1;
}
// Use the data, e.g., to print:
for(i = 0; i < count; i++) {
printf("%.*s = %s\n", klens[i], keys[i], vals[i]);
}
cleanup:
if(keys != NULL) free(keys);
if(vals != NULL) free(vals);
if(klens != NULL) free(klens);
如果您想拥有每个键和值的可写版本,您有两个选择:
strcpy
分别复制每个键和值。在这种情况下,清理会有点复杂,因为您必须在开头将keys
和vals
的所有元素设置为NULL
(例如使用memset
),并在完成后释放所有非NULL
元素。str
复制到新分配的可写缓冲区中,只需将=
替换为\0
即可。您可以在计算keys
和vals
的同时执行此操作。清理工作不会比以前复杂得多。你只需要释放额外的文本缓冲区。