• C

copy a substring and convert it into int

hi,

I got a string and i would like to copy a part of it and turn it into integer.

e.g.

temp_line="#version: 112233"

what i need is retrieve the 11, 22 and 33
and return them as integer.


thanx :p
LVL 1
KnightleyAsked:
Who is Participating?
 
Kent OlsenConnect With a Mentor Data Warehouse Architect / DBACommented:
Hi Knightley,

Brute force works just fine, but C has a functions to do just what you want.  

char *Str = "112233";
int    x, y, z;

  sscanf (Str, "%2d%2d%2d", &x, &y, &z);

The format can include all kinds of "skip" leading text, too.


You originally said that you want to "copy it and turn in into integer".  Copying it isn't necessary for converting it, but you can always copy the string (or any part of it) with other C functions if that's your wish.


Kent

0
 
van_dyCommented:
Here is a dirty one just suitable for above kindof strings;

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

void getintegers(string, num1, num2, num3, index)
                  char *string;
                  int *num1, *num2, *num3, index;
{
                  char *p = string + index;
                  int mynumber = atoi(p);
                   *num1 = mynumber / 10000;
                   mynumber %= 10000;
                   *num2 = mynumber / 100;
               mynumber %= 100;
                   *num3 = mynumber;
                    return;
}

int main()
{
      int num1, num2, num3;
      char *p = "#version: 112233";
        getintegers(p, &num1, &num2, &num3, 9);
      printf("%d %d %d\n", num1, num2, num3);
      return 0;
}
0
 
KnightleyAuthor Commented:
ok, i see what u mean, could i write the code like this:

int version;
char *temp_line="#version: 112233"

version= temp_line[10]%100000+
              temp_line[11]%10000+
              temp_line[12]%1000+
              temp_line[13]%100+
              temp_line[14]%10+
              temp_line[15];

and there is no problem that temp_line[i] is a char and version is a int???
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
ssnkumarCommented:
>temp_line="#version: 112233"
>i need is retrieve the 11, 22 and 33
>and return them as integer.
What is the criteria for scanning this string?
Should it start taking the character next to a "space"!?
Should it take 2 character at a time and convert it to int?
So, in the example you have shown, it has to convert it into 3 integers!?

If you can specify these requirements properly, then you may get a better code.
Otherwise, your code may not work for all the cases that might arise later!

-ssnkumar
0
 
stefan73Commented:
Hi Knightley,
Close. What you mean is probably:

version= (temp_line[10]-'0')*100000+
         (temp_line[11]-'0')*10000+
         (temp_line[12]-'0')*1000+
         (temp_line[13]-'0')*100+
         (temp_line[14]-'0')*10+
         (temp_line[15]-'0');


Cheers!

Stefan
0
 
van_dyCommented:
Hi Knightly,
         yea u get the point, actually as ssnkumar pointed out, there should be
a crteria to scan a string, like is it always going to begine with "#version: ", or
is the version number going to be broken up always in sets of 2 digits, as we did
here.  the actual algorithm u would implement to extract the numbers would depend
upon these details. hard coding magic numbers like we do in the call to getinegers(), [index = 9]
isnt a clean programming style.

hope this helps,
van_dy
0
 
KnightleyAuthor Commented:
stefan:
temp_line[10]-'0' will convert the "char" into a "int"?

van_dy:
yes, the "#version" and the number format always stay the same

Kent:
how do i change the sscanf function if my
char *Str="#version: 112233"

there is a space character behind "#version:" but i think this is not relevant?
0
 
KnightleyAuthor Commented:
actually i want to return the 11,22,33 as three integers
from a function.

Could c handle a array of integers?

if not i got to return 112233 as a single int, and then
divide it into 3 seperate integers.
0
 
ssnkumarCommented:
>Could c handle a array of integers?
YES and NO!
Actually you cannot return arrays. That's why NO.
But, you can simulate the same behaviour using pointers. That's why YES!

Then the code would change to:

int *func(char *str)
{
    int *int_arr = (int *) malloc(3 * sizeof(int));

    sscanf(str, "%2d%2d%2d", &int_arr[0], &int_arr[1], &int_arr[2]);

     return int_arr;
}

-ssnkumar
0
 
Kent OlsenData Warehouse Architect / DBACommented:

Hi Knightley,

There are lots of ways to skip text.  The simplest is to put the exact text into the format string.


char *Str ="#version: 112233";
int    x, y, z;

  sscanf (Str, "#version: %2d%2d%2d", &x, &y, &z);


More generic skip operations are also availabe that simply say "skip all alphabetic text".


Kent
0
 
van_dyCommented:
if your string is always going to contain 3 integers, each of 2 digits (xxyyzz)
then kent's solution is undoubtedly the best way to extract these;

char *Str = "#version: 112233";
int ver[3];
sscanf(Str + 10, "%2d%2d%2d", ver, ver + 1, ver + 2);

now the ver[] array will hold those integers.
0
 
stefan73Commented:
Knightley,
> temp_line[10]-'0' will convert the "char" into a "int"?

Sort of. In ASCII, numbers start with 48='0', 49='1', and so on. It's converting a character digit into the 0-9 range.

But don't use this, use a solution which is more sensitive to faulty input.
0
 
KnightleyAuthor Commented:
actually the format is "#version: 1122233"

so i need something like this?

char *Str = "#version: 1122233";
int ver[3];
sscanf(Str + 10, "%2d%3d%2d", ver, ver + 1, ver + 2);
0
 
Kent OlsenData Warehouse Architect / DBACommented:

It's a bit unusual to list the target variables (ver, ver+1, vet+2) that way, but it should work just fine!  I like it.  :)

Kent
0
 
van_dyCommented:
Hi Knightly,
     lol, well tell us first is it also possible to have following formats?
"#version: 1122333"      u need  11 22 333 ?
"#version: 1112233"      u need   111 22 33 ?
"#version:  111222333"  u need   111 222 333 ?
0
 
van_dyCommented:
in that case, we might need to go back to using the first method
0
 
KnightleyAuthor Commented:
:p

"#version: " is fixed, it coud be other text, like "#version_of_a_lousy_phone_OS: ".
But once set, it will not be changed.

the digits' format are alike, i do not know if it is 112233 or 11222233, but i know they are
together without spaces.

0
 
KnightleyAuthor Commented:
ssnkumar:

is your function like this

int *check_version()
{
    char *word="#version: 112233";

    int *int_arr = (int *) malloc(3 * sizeof(int));

    sscanf(str, "%2d%2d%2d", &int_arr[0], &int_arr[1], &int_arr[2]);

     return int_arr;
}
0
 
KnightleyAuthor Commented:
ahhh, i checkd with my boss, the "#version" is actually:

"#define FIRMWARE_VERSION_NUMBER "

the digits format is:

"1122233"
0
 
Kent OlsenData Warehouse Architect / DBACommented:

>> ahhh, i checkd with my boss.

Foolish.  But in this case, informative.  :)


Kent

------------------------------------------
Those who can, do.
Those who can not, teach.
Those who can not teach, manage!
------------------------------------------
0
 
KnightleyAuthor Commented:
i don't know where the files which contain
the "#define FIRMWARE_VERSION_NUMBER 1122233" string
are located on the server.

so i have to ask.

k
0
 
van_dyCommented:
Well did this just for the heck of it.
try running this.
----------------------------
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>

void getintegers(string, arrayint, size)
      char *string;
      int *arrayint;
      int *size;
{
      int index = 0;
      int index2;
      char ch1, ch2;
      while(!isdigit(ch1 = string[index]))
            index++;

      while(string[index]){
            arrayint[*size] = ch1 - '0';
            index2 = index + 1;
            while((ch2 = string[index2]) == ch1){
                  arrayint[*size] *= 10;
                  arrayint[*size] += ch2 - '0';
                  index2++;
            }
            ch1 = ch2;
            *size += 1;
            index = index2;
      }
}

int main()
{
      char *String = "Funny_String!@#@$#: 11133555999";
      int arrint[10];
      int size = 0;
      int i;
      getintegers(String, arrint, &size);

      for(i = 0; i < size; i++)
            printf("%d\n", arrint[i]);

      return 0;
}

:D
0
 
KnightleyAuthor Commented:
:D  Funny_String!@#@$#: 11133555999
0
 
van_dyCommented:
yea u can just put anything there and have ur numbers
0
 
Kent OlsenData Warehouse Architect / DBACommented:

The solution can still be reduced to a single line:

  sscanf (Str, "%*s %02d%03d%02d", ver, ver + 1, ver + 2);



Kent
0
 
ssnkumarCommented:
>ssnkumar
>is your function like this

YES.
But, sscanf part is just to show how to use it.
You can take the more reformed one of kdo.

Still we can have a general solution, only if you know the patterns of version numbers that can come in.
What about:
"#version:  123346"
How should this be scanned. Will it be 3 numbers (12, 33 and 46) or 5 numbers (1, 2, 33, 4 and 6)?

-ssnkumar
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.