我试图编写实用程序类型的函数,而不是太复杂,无法从分号分隔的字符串中提取值。在此示例中,我尝试提取X=bc
而我收到的内容是将值分配给*cpp
时的分段错误
我可能做错了什么?
int main()
{
char x[500]="a;X=bc;def;ghi";
char* cp=x,*cpp;
while ((cp=strstr(cp,";")))
{
cp++;
if ((*cp)=='X' && (*cp+1)=='=')
{
cp+=2;
break;
}
}
if ((cpp=strstr(cp,";")))
{
*cpp='\0';
}
printf("'%s' '%s'\n",x,cp);
return 0;
}
答案 0 :(得分:3)
这一行错了:
if ((*cp)=='X' && (*cp+1)=='=')
它应该是:
if ((*cp)=='X' && *(cp+1)=='=')
或更好:
if (cp[0]=='X' && cp[1]=='=')
请注意,编写的代码非常脆弱 - 有许多方法可能会失败 - 尝试并养成编程防御的习惯 - 始终假设任何可能失败的代码都会失败,相应地编写你的代码,这样当事情不按预期工作时,它至少会失败。
另一个提示,虽然我在这里:学习一些基本的调试技巧 - 我无法立即看到代码出了什么问题,所以我在代码中添加了一些printf以便我可以获得有关正在发生的事情的更多信息 - 很快就发现第一个循环之后cp
为NULL
,从那里更容易看到问题。或者我可以在调试器中逐步完成代码 - 这两种技术都会在一两分钟内直接导致这个错误。
答案 1 :(得分:1)
因为你得到了答案我只能告诉你另一种方法:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void checkString(char *string1, char *string2){
char *string3;
char *s1, *s2, *s3;
size_t lenstring1 = strlen(string1);
size_t lenstring2 = strlen(string2);
if (lenstring2 < 1){
printf("There is no substring found");
exit(1);
}
size_t i=0,j=0;
int found=0;
s1 = string1;
s2 = string2;
for(i = 0; i < lenstring1; i++){
if(*s1 == *s2){
s3 = s1;
for(j = 0;j < lenstring2;j++){
if(*s3 == *s2){
s3++;s2++;
}else{
break;
}
}
s2 = string2;
if(j == strlen(string2)){
found = 1;
string3=string2;
}
}
s1++;
}
if(found != 0){
printf("%s\n",string3);
}else{
printf("No match Found");
}
}
int main(void){
char string1[] = "a;X=bc;def;ghi";
char string2[] = "X=bc";
checkString(string1, string2);
return 0;
}
输出:
X = BC
答案 2 :(得分:1)
您可能希望使用标准库函数strtok
,这听起来非常适合此任务。它需要一个字符串并根据作为参数给出的分隔符或分隔符将其分隔为标记。
此代码可以帮助您入门:
#include <stdio.h>
#include <string.h>
int main(void)
{
char *token;
char *parsed;
char input[] ="a;X=bc;def;ghi";
parsed = input;
while(token = strtok(parsed, ";"))
{
parsed = NULL;
puts(token);
}
return 0;
}
对strtok
的第一次调用使用要解析的实际字符串作为第一个参数,而以下调用使用NULL
。如果没有其他令牌(或根本没有令牌),strtok
会返回NULL
。
使用此功能时需要注意以下几点:
char *strtok(char *str, const char *delim);
。这意味着str
必须是可写的。因此,您不能假设它将保持不变。strtok
将导致错误,因为它使用全局状态来存储最后返回的令牌。 POSIX定义了此函数的线程安全形式,其原型为char *strtok_r(char *str, const char *delim, char **saveptr);
,最后一个参数用于在调用之间存储数据。使用这样的接口,不需要使用全局状态,因为saveptr
可以存储为局部变量。此功能的documentation应该可以回答您的所有疑问。