gpt4 book ai didi

c - C中的解析问题

转载 作者:行者123 更新时间:2023-11-30 17:46:02 26 4
gpt4 key购买 nike

我有一个格式为的字符串:

char *sampleLine = "name1: 251 name2: 23 name3: -67 name4: 0.00 name5: 310 name6: 410 name7: 54001 name8: 332 name9: SOME_TEXT name10: 3 name1: 181 235 237 name11: 11 name12: 240 241 242 243 244 245 246 247 248 249 250 name13: 0 name14: 2 name15: 1 name16: 0 name17: 6 name18: 0 name19: 500 name20: 200 name21: 64 name22: 1 name23: 6 name24: 0 name25: 0";

该字符串的问题之一是某些名称重复,但基本模式似乎是名称:值。所以我编写了一个算法,它会接受一个名称并返回一个值,但它似乎不起作用,并且没有考虑名称重复的问题。

例如:如果我传入 name1,我期望得到 251 等。

这是带有示例主代码的代码:

#include <stdio.h>                                                              
#include <stdlib.h>
#include <string.h>
#include <strings.h>

char* extractValue(char* name, char* buffer)
{
char* begining = strstr(buffer,name);
begining += strlen(name) + 2;

if (begining != NULL)
{
char* end = strstr(begining,":");

if (end != NULL)
{
end += 1;

for (int i=0; i < strlen(end); i++)
{
if (end[i] != ':')
{
i++;
} else {
char namevalue[200];
bzero(namevalue,200);

strncpy(namevalue,begining,i);

for (int x=strlen(namevalue); x>0; x--)
{
if (namevalue[x] == ' ')
{
char* value = (char*)malloc(200);
bzero(value,200);

strncpy(value,namevalue,strlen(namevalue) - (strlen(namevalue) - x));

return value;
}
}
break;
}
}
}
}
return NULL;
}


int main (int argc, char** argv)
{
char *sampleLine = "name1: 251 name2: 23 name3: -67 name4: 0.00 name5: 310 name6: 410 name7: 54001 name8: 332 name9: SOME_TEXT name10: 3 name1: 181 235 237 name11: 11 name12: 240 241 242 243 244 245 246 247 248 249 250 name13: 0 name14: 2 name15: 1 name16: 0 name17: 6 name18: 0 name19: 500 name20: 200 name21: 64 name22: 1 name23: 6 name24: 0 name25: 0";

char* value1 = extractValue("name1", sampleLine);
char* value3 = extractValue("name3", sampleLine);
char* value17 = extractValue("name17", sampleLine);

printf("value 1 = %s\n",value1);
printf("value 3 = %s\n",value3);
printf("value 17 = %s\n",value17);

return 0;
}

当我运行它时,我得到:

$ gcc -Wall -std=c99 -o parse parse.c && ./parse
value 1 = 251 name2: 23
value 3 = -67 name4: 0.00
value 17 = 6 name18: 0 name19: 500 name20: 200 name21:

与预期不同

value 1 = 251
value 3 = -67
value 17 = 6

最佳答案

两个细微的错误。

首先

if (end[i] != ':')
{
i++;
} else ..

通过在此处手动递增 i,您将跳过一个字符,因为 i 已通过 for 循环递增。它似乎没有副作用,但这只是因为......

第二:问题的实际原因是您正在测量错误字符串的长度。您可以通过从该位置向前扫描下一个 : 来找到名称值的开头 (begining),然后找到其 end。然后,向后跟踪找到前一个空格,这应该是值的末尾。但是...

for (i=0; i < strlen(end); i++)

从字符串的(已确定)末尾开始检查向前!当然,对于您的测试名称,您一定会在更远的地方找到冒号 - 但它的位置与您感兴趣的字符串无关,该字符串位于 begining 之间结束

i 循环更改为

for (i=0; i < end-begining; i++)

并将 : 检查更改为

if (begining[i] == ':')
{
char namevalue[200];
... (etc.)

(丢弃 i++ 行)。

<小时/>

松散的笔记

查找单个字符的稍微快一点的方法是 strchr:

char* end = strchr(begining,':');

您可能希望找到更好的策略来定位名称。如果您正在查找 name1,它可能会找到 name12 以及 noname1

一种方法是使用 strtok 将字符串拆分为标记。那么任何以 : 结尾的都是一个潜在的名称,下一个标记就是您要查找的值。省略,因为它本身就是一个很好的练习。 (如果你想尝试这个:strtok modifies the original string!)

最后,您可以不需要所有这些循环:-)

char* extractValue(char* name, char* buffer)
{
char *start, *end, *ret_val;
int length;
char* begining = strstr(buffer,name);
if (!begining)
return NULL;
start = begining + strlen(name);
if (start[0] != ':')
return NULL;
start++;

// skip initial spaces, if any
while (*start == ' ')
start++;
// ptr points to the start of data. Find end.
end = start;
while (*end && *end != ' ')
end++;

// we have the correct string in start..end
length = end-start;

// it's a zero-terminated string so add 1 for the zero
ret_val = (char *)malloc(length+1);
strncpy (ret_val, start, length);
// put the zero where it belongs
ret_val[length] = 0;

return ret_val;
}

关于c - C中的解析问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19472097/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com