Hi guys,

i'm new here and new to c/c++ programming.
could you guys guide me how to extract some character/number from a char string?

Example:
char = TAGNAME_C123_V45_S67_M89
i want to extract the numerical number next to the character. The TAGNAME and the number is varies. So my code should cater different number and TAGNAME, but the C,V,S & M shall always be there.

something like arguments.

Pls help.Thanx a lot

well i would do something like this:

...// i skipped the beginning of the code: char a etc...

if (a==C){/* a is variable user enters via keyboard(next to which are info you want to extract)*/
  printf("%c, %c, %c",str[10], str[11], str[12]);//str is your string
}
break;
else if (a==V) {
  printf("%c, %c, %c", str[15], str[16]);//
}
break;
else if(a==S){
  printf(....)....

remember that string is similar to array so that is why you could use str[some number]...but not the same of course...
Why str[10], str[11]...? because those are places of character you want to extract in your string...this logic can be used only if your string is exactly as you said (length of its name doesn't varies -in this case TAGNAME...A,C,S,V doesn't change...)
and i am not sure what do you mean by "extract"...Please give some more details so i could give you more specific answer...
hopes this help...ask whatever you don't understand...

This is what sscanf was born to do:

#include <stdio.h>

int main()
{
    const char *p = "TAGNAME_C123_V45_S67_M89";
    int c, v, s, m;

    if (sscanf(p, "%*[^_]_C%d_V%d_S%d_M%d", &c, &v, &s, &m) == 4)
    {
        printf("C=%d\nV=%d\nS=%d\nM=%d\n", c, v, s, m);
    }

    return 0;
}

Loop through and convert the group of characters next to c's,v's,m's ..... into integer datatype, take each character and change ascii value or perhaps use atoi function and multiply by powers of 10. You'll get your required numbers

Comments
what in the hell are you talking about?
Fail! Are we going to make things difficult? Just use sscanf() !!

how to extract some character/number from a char string?

Example:
char = TAGNAME_C123_V45_S67_M89

what you have written here is an identifier from a #define 'd constant -- not a string.

if it were a string, then you could use sscanf() as Tom Gunn suggested. but he's assumed that you really meant to put something like char *p = "TAGNAME_C123_V45_S67_M89"; ... and that is not what you wrote, since it was not in quotes.

if TAGNAME_C123_V45_S67_M89 is a constant identifier -- as it appears to be -- then you can not merely use sscanf() to extract substrings out of the identifier name. it becomes more complicated, and you will have to rewrite a significant amount of code.

if you truly meant it to be a string, then it must be in quotes and either (1) assigned when declared as a const char * , as Tom suggested, or (2) assigned later with a function like "strcpy()"

the difference is important, and will significantly affect how you accomplish what you want to do.

.

This is what sscanf was born to do:

#include <stdio.h>

int main()
{
    const char *p = "TAGNAME_C123_V45_S67_M89";
    int c, v, s, m;

    if (sscanf(p, "%*[^_]_C%d_V%d_S%d_M%d", &c, &v, &s, &m) == 4)
    {
        printf("C=%d\nV=%d\nS=%d\nM=%d\n", c, v, s, m);
    }

    return 0;
}

You're right..I wasn't familiar with sscanf function...I learnt something new today..:) although I don't understand why did you use IF condition ...?

although I don't understand why did you use IF condition

this is not your thread to ask basic questions. go open your own thread on how to use IF.

and if you don't know how to use sscanf() -- much less how to look it up -- then you damn sure need to quit "helping" people.

.

this is not your thread to ask basic questions. go open your own thread on how to use IF.

and if you don't know how to use sscanf() -- much less how to look it up -- then you damn sure need to quit "helping" people.

.

What...?You're obviously an idiot because you can't make a difference between not knowing some function and not knowing where to find explanation how that function works and what it is used for...As you can see i wrote "I learnt something new today" which means i didn't know it before but i know and understand it now...

And besides that if you think you are so smart , which you obviously are NOT, you could have understand why i didn't understand why he used if condition....I asked him that because i think its not necessary to use it in solving this problem...(Maybe i made a mistake but that is not a problem...)Not because i don't know how or where to use IF or anything else....In the end i used IF in my version of solution which means i understand how it works...

This forum is made for helping people, whatever their problem in programming is not for some egoistic retard like you to heal his emotional problems by making other people look stupid (look stupid in his eyes and his disturbed mind, of course)...

Comments
damn sure doesn't deserve pos rep.
May be arogant, but right in saying that he was asking about the use of If in this context and not the general usage.
Sorry buddy, but I have to agree with jephthah, as a forum rule dictates: "Search for your answers first" or are you too lazy for that?

[...] although I don't understand why did you use IF condition ...?

sscanf() returns EOF if it fails or the number of items that has been successfully read. By using an if statement a minimum of checking has been accommodated. It is imperative to check the return of functions. How does the saying goes?: Assume makes an ass out of u and me.

HI guys,

cool down, i guess everyone here is to learn a thing or two from each other. So don't get piss off. I don't mind others asking question in this thread. It'll help me to learn as well.

to jephthah: Yes is a string. Sorry for not making it clear.
to Tom Gunn: Thanx for you input. I shall try your method.
to others: thanx for giving some input.

Hi guys.

sorry is me again.
what if the char *p = "TAG_NAME_C123_V45_S67_M89"
I've try to change the argument from the code provided by Tom Gunn but failed. What i'm trying to do is ignore whatever is in front as long the string has/end with the "_CXXX_VXX_SXX_MXX".

how to ignore whatever character or number in front? Only need to extract the number after "_C", "_V", "_S" & "_M" This 4 parameter will be located at the end of the string.

The front string can be anything, for example:
1) ABC_DEF_GHI_JKL
2) A11_BCDEF_CADT1
3) etc

pls help.! thanx

nonadoes> Only need to extract the number after "_C", "_V", "_S" & "_M"
Search for character _ and when you find it skip one more and that's the number you want.

phew...i finally get it done.
here how i do it. Not great, but get the work done. Pls advice to improve it.

const char line[] = "SEFDF_CC_C444_QWEEEE123124234_AC_C123_V45_S67_M89";
int n, c, v, s, m;
char field[30];
const char *ptr = line;

while(sscanf(ptr, "%*29[^_]%n", field, &n) == 1)
{
    if(sscanf(field, "C%d", &c) == 1)
        printf("C=%d\n", c);

    if(sscanf(field, "V%d", &v) == 1)
        printf("V=%d\n", v);

    if(sscanf(field, "S%d", &s) == 1)
        printf("S=%d\n", s);

    if(sscanf(field, "M%d", &m) == 1)
        printf("M=%d\n", m);

    ptr += n;
    if(*ptr1 != '_')
    {
        break;
    }
    ++ptr;
}

Any comment how to improve this? Thanx alot.!

Edited 3 Years Ago by Reverend Jim: Fixed formatting

I assumed that _C was unique, but that was wrong. Regular expressions are perfect for this, but you can do it manually too:

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

int MatchCvsmPattern(const char *str, int values[4])
{
    /* find the starting value */
    while (str = strstr(str, "_C"))
    {
        const char *fmt = "_C%d_V%d_S%d_M%d%n";
        int c, v, s, m;
        int end = 0;

        /* match the pattern */
        if (sscanf(str, fmt, &c, &v, &s, &m, &end) == 4)
        {
            values[0] = c;
            values[1] = v;
            values[2] = s;
            values[3] = m;

            /* check for a pattern at the end of the string */
            if (str[end] == '\0') return 1;
        }

        str += 2; /* skip "_C" */
    }

    return 0;
}

int main()
{
    const char *samples[] = 
    {
        "ABC_DEF_GHI_JKL_C123_V45_S67_M89",
        "A11_BCDEF_CADT1_C123_V45_S67_M89",
        "TAG_NAME_C123_V45_S67_M89",
        "SEFDF_CC_C444_QWEEEE123124234_AC_C123_V45_S67_M89"
    };
    int x;

    for (x = 0; x < sizeof samples / sizeof *samples; ++x)
    {
        int values[4] = {0};

        if (MatchCvsmPattern(samples[x], values))
        {
            printf("%d: C=%-4dV=%-4dS=%-4dM=%-4d\n", 
                x, values[0], values[1], values[2], values[3]);
        }
    }

    return 0;
}

You said that the values are at the end, so I put extra tests in there to make sure any matching pattern is the last thing in the string. If your way works then it works. Mine is just another way. :)

I assumed that _C was unique, but that was wrong. Regular expressions are perfect for this, but you can do it manually too:

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

int MatchCvsmPattern(const char *str, int values[4])
{
    /* find the starting value */
    while (str = strstr(str, "_C"))
    {
        const char *fmt = "_C%d_V%d_S%d_M%d%n";
        int c, v, s, m;
        int end = 0;

        /* match the pattern */
        if (sscanf(str, fmt, &c, &v, &s, &m, &end) == 4)
        {
            values[0] = c;
            values[1] = v;
            values[2] = s;
            values[3] = m;

            /* check for a pattern at the end of the string */
            if (str[end] == '\0') return 1;
        }

        str += 2; /* skip "_C" */
    }

    return 0;
}

int main()
{
    const char *samples[] = 
    {
        "ABC_DEF_GHI_JKL_C123_V45_S67_M89",
        "A11_BCDEF_CADT1_C123_V45_S67_M89",
        "TAG_NAME_C123_V45_S67_M89",
        "SEFDF_CC_C444_QWEEEE123124234_AC_C123_V45_S67_M89"
    };
    int x;

    for (x = 0; x < sizeof samples / sizeof *samples; ++x)
    {
        int values[4] = {0};

        if (MatchCvsmPattern(samples[x], values))
        {
            printf("%d: C=%-4dV=%-4dS=%-4dM=%-4d\n", 
                x, values[0], values[1], values[2], values[3]);
        }
    }

    return 0;
}

You said that the values are at the end, so I put extra tests in there to make sure any matching pattern is the last thing in the string. If your way works then it works. Mine is just another way. :)

Hi Tom Gunn,
Thank you so much for your input. This is exactly what i wanted to do. Another is to verify whether CVSM located at the end. I did a modification from my code earlier to achieve this. But i think is very silly. I use alot "if" case. I think your code is more simpler, clean and versatile. Thank you so much for the guidance.!!

This question has already been answered. Start a new discussion instead.