before you edit your question
the call
sscanf("!%[^!]! - %d %d - ",string,&a,&b);
is not the one you want, you missed to give the string to parse as the first argument, so the string to parse is the format you wanted to use and the used format is the perhaps not initialized value of string
You wanted :
#include <stdio.h>
int main()
{
char string[32];
int a,b;
const char * i = "!Hello world! - 123 123 -";
if (sscanf(i, "!%31[^!]! - %d %d - ", string,&a,&b) == 3)
printf("'%s' %d %d\n", string, a, b);
else
put("error");
return 0;
}
does the work :
pi@raspberrypi:/tmp $ gcc -Wall f.c
pi@raspberrypi:/tmp $ ./a.out
'Hello world' 123 123
pi@raspberrypi:/tmp $
Notice I added in your original format a max length for the read string to not take the risk to write out of string and then to have an undefined behavior. If you do not want to manage yourself the array for string you can use the option %m
but is not always available.