-1

I started learning C language about 1 week, and I'm trying to build my first programs. I'm coming from Python, so the C syntax isn't very clear for me, and I haven't understand the solutions that I found online. So, if I have this string:

char str[50] = "dimension[1080,720];"

and i want to create two integer variables that containes 1080 and 720 and string var that contains the first string. But these two numbers can change, and they can have random cifras. So, i wanted my output is

int x = 1080
int y = 720

*the values are always two, but the lenght can change. How can i do that?


Second version:

So, if I have this string:

char str[50] = "dimension["string",1080,720];"

and i want to create two integer variables that containes 1080 and 720 and string var that contains the first string. But these two numbers can change, and they can have random cifras. So, i wanted my output is

char str[1000] = "string";    
int x = 1080
int y = 720

the values are always three, but the lenght can change. How can i do that?

0___________
  • 60,014
  • 4
  • 34
  • 74
JacopoBiondi
  • 57
  • 1
  • 7
  • So your question is "How to parse two integers contained in the string"? – UnholySheep Aug 19 '22 at 11:49
  • 1
    You could try : https://stackoverflow.com/questions/13399594/how-to-extract-numbers-from-string-in-c – FreudianSlip Aug 19 '22 at 11:53
  • @user3121023 yes, i've write 20 for the post, but in original post is 50, now i correct – JacopoBiondi Aug 19 '22 at 11:55
  • `"dimension["string",1080,720];"` does not look like a valid string. You should take the time to provide a proper example of what you are trying to work with – UnholySheep Aug 19 '22 at 11:57
  • 1
    Do you mean `char str[50] = "dimension[\"string\",1080,720]";` that would actually compile, or something else? Hard to answer something that doesn't compile and keeps changing. – Retired Ninja Aug 19 '22 at 11:57
  • It is absolutely unclear what you are trying to do. Maybe you can show a Python equivalent. – n. m. could be an AI Aug 19 '22 at 12:35
  • Being pedantic, Sheep & Ninja, this can compile depending on what the token `string` resolves to (e.g., macro of string literal: https://godbolt.org/z/vfnxzd7Ez). Unlikely to be the case, but this is why, @JacopoBiondi, a proper [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) showcasing an actual attempt is very important to avoid confusion. – Oka Aug 19 '22 at 12:42

2 Answers2

4

use sscanf function

int main(void)
{
    char str[] = "dimension[1080,720];";
    int x,y;

    if(sscanf(str, "dimension[%d,%d", &x, &y) != 2) {printf("Error\n");}
    else printf("X=%d Y=%d", x, y);
}

Question two:

int main(void)
{
    char str[] = "dimension[\"string\",1080,720];";
    char str1[20];
    int x,y;

    char *ptr = strstr(str, "[");
    char *ptr1;
    size_t len;
    
    memcpy(str1, ptr + 2, len = (ptr1 = strchr(ptr + 2, '"')) - (ptr + 2));
    str[len] = 0;

    if(sscanf(ptr1 + 2, "%d,%d", &x, &y) != 2) {printf("Error\n");}
    else printf("Str = %s X=%d Y=%d", str1, x, y);
}
0___________
  • 60,014
  • 4
  • 34
  • 74
1

The sscanf answer is perfect, but not very flexible. I add this in case you want more flexibility to parse strings. You can do it with regular expressions and in your case would be something like:

Piece of code taken from https://gist.github.com/ianmackinnon/3294587 I have added some modification to extract the numbers to the variables

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


int main ()
{

  // Define regexp and input
  char * source = "dimension[\"string\",1080,720];";
  char * regexString = "[a-z]+\\[\"([a-z]+)\",([0-9]+),([0-9]+)\\]";
  size_t maxMatches = 3;
  size_t maxGroups = 4;

  // Variables we want to extract from the input
  char*  str;
  int    n1;
  int    n2;
  

  regex_t regexCompiled;
  regmatch_t groupArray[maxGroups];
  unsigned int m;
  char * cursor;

  if (regcomp(&regexCompiled, regexString, REG_EXTENDED))
    {
      printf("Could not compile regular expression.\n");
      return 1;
    };

  m = 0;
  cursor = source;
  for (m = 0; m < maxMatches; m ++)
    {
      if (regexec(&regexCompiled, cursor, maxGroups, groupArray, 0))
        break;  // No more matches

      unsigned int g = 0;
      unsigned int offset = 0;
      for (g = 0; g < maxGroups; g++)
        {
          if (groupArray[g].rm_so == (size_t)-1)
            break;  // No more groups

          if (g == 0)
            offset = groupArray[g].rm_eo;

          char cursorCopy[strlen(cursor) + 1];
          strcpy(cursorCopy, cursor);
          cursorCopy[groupArray[g].rm_eo] = 0;
          printf("Match %u, Group %u: [%2u-%2u]: %s\n",
                 m, g, groupArray[g].rm_so, groupArray[g].rm_eo,
                 cursorCopy + groupArray[g].rm_so);

          switch (g)
          {
            case 1:
                // Copy to the string now that we know the length
                str = malloc(strlen(cursor)+1);
                strcpy(str,cursorCopy + groupArray[g].rm_so);
                break;
            case 2:
                n1 = (int) strtol(cursorCopy + groupArray[g].rm_so, (char **)NULL, 10); //(cursorCopy + groupArray[g].rm_so,10);
                break;
            case 3:
                n2 = (int) strtol(cursorCopy + groupArray[g].rm_so, (char **)NULL, 10); //(cursorCopy + groupArray[g].rm_so,10);
                break;

          }

        }
      cursor += offset;
    }

  regfree(&regexCompiled);


  printf("Matches in variables: %s - %d - %d \n",str,n1,n2);

  return 0;
}

This for me prints

Match 0, Group 0: [ 0-28]: dimension["string",1080,720]
Match 0, Group 1: [11-17]: string
Match 0, Group 2: [19-23]: 1080
Match 0, Group 3: [24-27]: 720
Matches in variables: string - 1080 - 720 

Fra93
  • 1,992
  • 1
  • 9
  • 18