3

I have searched and read that the ^ modifier states to ignore whatever you put inside of the [ ] in scanf. For example:

int val;   
scanf("%[^abc] %d, &val);  
printf("val is %d", val);  

Now, if I input abc42, I thought the abc would be ignored and 42 would get stored into val. But, this doesn't happen.

I also tried to suppress the scanf by making it:

scanf("%*[^abc] %d, &val);

but this did not work either. So I am confused on what ^ actually does.

Nekresh
  • 2,948
  • 23
  • 28
  • 1
    Your code sample has mismatched quotes. Please post exactly the code you are trying – M.M Oct 12 '15 at 07:40

3 Answers3

6

When you say you want scanf to ignore certain characters, I think you mean you want scanf to read those characters and then ignore them. In order to do that, you use the %*[] format specifier:

scanf("%*[abc] %d", &val);

The [abc] tells scanf to read any number of the characters between the brackets (i.e. a, b, or c). The * tells scanf to ignore those characters, then the %d reads the value into val.

The ^ specifier tells scanf to read any number of characters other than those in between the brackets, which is the opposite of what you want to do, I think.

godel9
  • 7,340
  • 1
  • 33
  • 53
5

You need to carefully read the documentation of scanf(3) and to enable all warnings when compiling (e.g. gcc -Wall -Wextra -g if using GCC...); you'll probably have been warned with such a compilation. You should also use the result of scanf and run your program in a debugger (gdb)

scanf("%[^abc] %d", &val);  

is reading two items, the first being a string of characters outside of the set {a,b,c} (and the second being an integer going "nowhere").

So your program has undefined behavior (UB) because you call scanf with one argument less than it should, and because the first argument should be the location of a wide enough char buffer. UB can be really bad, so you need to always avoid it.

You might try:

int val= 0;
char buf[32]; // 30+1 could be enough....
memset (buf, 0, sizeof(buf));
if (scanf("%30[^abc] %d", buf, &val) == 2) {
  printf("got string %s and int %d\n", buf, val);
}
else { // handle scanf failure 
}
Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
2

It gives the following warning message when I am compiling the code.

test.c:5:2: warning: format ‘%[^abc’ expects argument of type ‘char *’,but argument 2 has type 'int *’ [-Wformat]
test.c:5:2: warning: format ‘%d’ expects a matching ‘int *’ argument [-Wformat]

You have to pass the character array to the scanf function, when you are using this.

So, modify the scanf line to bellow, and check what happens.

char buf[100];
int val;
scanf("%[^[abc] %d",buf,&val);

The %[^abc] it reads the string, if any character in the bracket other than the ^ is occurs it will fill the address of the character array with the reading characters. So, this is used only when we are reading the string input.