2

I need to get integers from a string that an user enters into the console.

For exemple: I have this string: [1, 2, 3, 4, 5] and I would like to get all of the integers from it. I already tried multiple scanf patterns, such as scanf("%*[^\[]%d,", &a), but nothing worked. I couldn't find anything relevant on Stack Overflow either.

The main problem is that he can enters between 1 and 50 integers into his string. I have no idea about how to stock only integers (removing ',' and '[' ']' ) into an array.

Some solutions have been found for removing special chars such as [ ] or , But now I still need to remove SPACE between comas and integers...

EDIT : problem solved using fgets. I was using scanf to get my string, but it were stopping to SPACES.

Fond out how to do that with scanf :

while(scanf(" %d",&i))

Nark
  • 454
  • 1
  • 7
  • 18
  • 1
    Have you seen this link? http://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c – Marievi Jan 17 '17 at 08:50
  • 1
    I voted to close, since the question is unclear, and essentially asking for help getting code working which is not shown. `scanf()` is not used to read from strings at all, so no "patterns" will work. `sscanf()` [note the double `s`] might be used for that purpose. – Peter Jan 17 '17 at 08:55
  • Advice: don't parse with `scanf` and friends, period. You can use `scanf` only if the input is predetermined. – Jabberwocky Jan 17 '17 at 09:24
  • Be more specific. is it a string (i.e. an array of chars) or an array of integers? (since you are stating you want to get integers from it). I am going to assume you mean an array of chars, then you can access each element if a loop like this: for (int i = 0; i < sizeof(arr)/sizeof(char); ++i) arr[i] = //do something – Marius Jan 17 '17 at 08:51
  • It is a string of chars, that's something user have to enter into the console, I need to get integers from the string. He gives me something like [1,50,60], I need to stock only the integers somewhere. – Nark Jan 17 '17 at 09:12
  • Welcome to Stack Overflow! Please [edit] your question to show [what you have tried so far](http://whathaveyoutried.com) and a clear description why each attempt is insufficient. You should include a [mcve] of the code that you are having problems with, then we can try to help with the specific problem. You should also read [ask]. – Toby Speight Jan 17 '17 at 10:49

3 Answers3

2

scanf/sscanf does not support regular expressions. You should try something like:

const char my_string[] = "[1,2,3,4,5]";
int a,b,c,d,e;
sscanf(my_string, "[%d,%d,%d,%d,%d]", &a, &b, &c, &d, &e);

Example: http://ideone.com/AOaD7x

It can also be good to check the return value of scanf/sscanf:

int retval = sscanf(my_string, "[%d,%d,%d,%d,%d]", &a, &b, &c, &d, &e);
if (retval != 5)
    fprintf(stderr, "could not parse all integers\n");

Reference

Edit: In your edited question you asks how to do this if there is a variable number of integers. You can use strchr to locate the next comma in the string and continue to iterate until no more comma is found. This assumes that the string ends with ].

const char my_string[] = "[1,2,3,4,5]";

/* start at first integer */
const char *curr = &my_string[1];

while (curr != NULL) {
    /* scan and print the integer at curr */
    int tmp;
    sscanf(curr, "%d", &tmp);
    printf("%d\n", tmp);

    /* find next comma */
    curr = strchr(curr, ',');

    /* if a comma was found, go to next integer */
    if (curr)
        /* warning: this assumes that the string ends with ']' */
        curr += 1;
}

Example: http://ideone.com/RZkjWN

simon
  • 2,042
  • 2
  • 20
  • 31
  • Okey thanks, but my main problem is that I have no idea how many numbers can be into the string. I mean : there wont be more then 50 numbers, but I the number of integers in the string isn't a const. – Nark Jan 17 '17 at 09:08
  • Iterate and call sscanf (with an offset) until it returns zero. – simon Jan 17 '17 at 09:13
  • I don't get it : how can you do itterations with a sscanf with a const string. I mean : the string will never change for each interration, so it will be endless right? I just tried to itterate with scanf("%c%d", &test, &tab[0]); and scanf never ends... – Nark Jan 17 '17 at 09:22
  • Why not use `sscanf(my_string, "[%d,%d,%d,%d,%d", &a, &b, &c, &d, &e);` (no `]`)? Using it gives the false impression that the input string is somehow tested for the presence of `]`. – chux - Reinstate Monica Jan 17 '17 at 15:49
1

Try this piece of code, by using strtok you can separate out all type of unwanted characters in your string. Add all your unwanted set of character to this s array and let strtok do the work.

char str[]="[1,2,3,4,5]";
const char s[4] = "[],"; // All unwanted characters to be filtered out
char *token;
token = strtok(str, s);
while( token != NULL ) 
{
  printf( "%d\n", atoi(token));
  token = strtok(NULL, s);
}

Since you have it in the integer format, you could store it in an array and go further with it.

Output :

1
2
3
4
5
sameera sy
  • 1,708
  • 13
  • 19
  • It works perfectly well thanks a lot! But I still have a little problem : I need to put spaces into the string (ex : [1, 2, 3] and I can't set the "SPACE" char into unwanted chars... Is there a way to bypass this? – Nark Jan 17 '17 at 12:24
  • I tried to add octal code '\040' into the const char s[5] = "[],'\040'"; but it looks like GCC doesn't understand what I want to do. – Nark Jan 17 '17 at 12:42
  • @Nofix Even if there is space in your string, the tokeniser works just fine, Check this out, i added space in the string and the code just works fine by printing out only integers https://ideone.com/edSfup – sameera sy Jan 18 '17 at 03:01
  • @Nofix Did you check it out? – sameera sy Jan 18 '17 at 06:26
0

Using scanf() for parsing strings is not recommended.

Similarly to others answers, you can use strtok to parse the numbers between "[],", and convert the found numbers using strtol. It would be dangerous to use something like atoi() for integer conversion, as their is no error checking with it. Some more error checking with strtol() can be found in the man page.

Here is some sample(can be improved) code which does this:

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

#define MAXNUM 50
#define BASE 10

int main(void) {
    char string[] = "[1,2,3,4,5]";
    char *number, *endptr;
    const char *delim = "[],";
    int numbers[MAXNUM], current;
    size_t i, count = 0;

    number = strtok(string, delim);
    while (number != NULL) {
        current = strtol(number, &endptr, BASE);

        /* checking if valid digit found */
        /* more error checking can be added */
        if (endptr != number) {
            numbers[count++] = current;
        }
        number = strtok(NULL, delim);
    }

    for (i = 0; i < count; i++) {
        printf("numbers[%zu] = %d\n", i, numbers[i]);
    }

    return 0;
}

Sample input 1:

string[] = "[1,2,3,4,5]";

Output 1:

numbers[0] = 1
numbers[1] = 2
numbers[2] = 3
numbers[3] = 4
numbers[4] = 5

Sample input 2:

string[] = "[1,a,3,c,5]";

Output 2:

numbers[0] = 1
numbers[1] = 3
numbers[2] = 5
RoadRunner
  • 25,803
  • 6
  • 42
  • 75