在C中的两个分号之间提取数据

时间:2015-10-20 21:12:40

标签: c pointers substring

我试图编写实用程序类型的函数,而不是太复杂,无法从分号分隔的字符串中提取值。在此示例中,我尝试提取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;
}

3 个答案:

答案 0 :(得分:3)

这一行错了:

    if ((*cp)=='X' && (*cp+1)=='=')

它应该是:

    if ((*cp)=='X' && *(cp+1)=='=')

或更好:

    if (cp[0]=='X' && cp[1]=='=')

请注意,编写的代码非常脆弱 - 有许多方法可能会失败 - 尝试并养成编程防御的习惯 - 始终假设任何可能失败的代码都会失败,相应地编写你的代码,这样当事情不按预期工作时,它至少会失败

另一个提示,虽然我在这里:学习一些基本的调试技巧 - 我无法立即看到代码出了什么问题,所以我在代码中添加了一些printf以便我可以获得有关正在发生的事情的更多信息 - 很快就发现第一个循环之后cpNULL,从那里更容易看到问题。或者我可以在调试器中逐步完成代码 - 这两种技术都会在一两分钟内直接导致这个错误。

答案 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

使用此功能时需要注意以下几点:

  1. 原型是char *strtok(char *str, const char *delim);。这意味着str必须是可写的。因此,您不能假设它将保持不变。
  2. 如果您打算在程序中使用线程,从多个线程调用strtok将导致错误,因为它使用全局状态来存储最后返回的令牌。 POSIX定义了此函数的线程安全形式,其原型为char *strtok_r(char *str, const char *delim, char **saveptr);,最后一个参数用于在调用之间存储数据。使用这样的接口,不需要使用全局状态,因为saveptr可以存储为局部变量。
  3. 此功能的documentation应该可以回答您的所有疑问。