%[^a] in scanf

V

vamshi

main()
{
char str[20];
printf("Enter a string: ");
scanf("%[^a]",str);
printf("%[^a]",str);
}

Can some one help me with this code?
when i tried to execute this..... it reads the string untill character
' a ' and copies to str.
after 'a' everything else we type is discarded.
where can this be used? how exactly it is working?
is it making ^ operation on read data and when 'a' is pressed the ^
operation value turns out to be 0 which is string termination. is it
so? can i use other operators also instead of ^?
will it work on int and other data types?
whats the use of %[^a] in printf?

Thanks in advance....
Vamshi.
 
R

Richard Bos

vamshi said:
main()
{
char str[20];
printf("Enter a string: ");
scanf("%[^a]",str);
printf("%[^a]",str);
}

Can some one help me with this code?

Sure. First, remove the bugs. This includes at the very least 1.
#including relevant headers and 2. not reading random-length input into
fixed-length arrays. Fixing the declaration of main() would also be
good.
when i tried to execute this..... it reads the string untill character
' a ' and copies to str.
after 'a' everything else we type is discarded.

Yes... what did you expect? You are asking scanf() to match a scanset
that consists of any number of characters not from the list "a". And
that's what it's doing.
is it making ^ operation on read data

Not at all. The ^ operator and the ^ in the scanset conversion specifier
have no more to do with one another than the % operator and the % in
conversion specifiers...
can i use other operators also instead of ^?

....so no, you can't...
will it work on int and other data types?

....and no, it won't.

Look up the *scanf() functions in your C textbook, and find where it
explains the [] conversion specifier. It's quite useful, and any halfway
decent book on C should explain it.
whats the use of %[^a] in printf?

Nothing. Using the [] specifier in printf() at all, with or without ^,
invokes undefined behaviour. So don't do that.

Richard
 
S

santosh

vamshi said:

Use the canonical int main(void) or int main(int argc, char **argv).
{
char str[20];
printf("Enter a string: ");

Either end output with a newline or call fflush(stdout), or your prompt
is not guaranteed to appear.
scanf("%[^a]",str);

scanf() is second only to gets() in being unsuited for string input.
fgets() is better suited for this job. A function like CBFalconer's
ggets(), (search the group for source), is even better.
printf("%[^a]",str);

This evokes undefined behaviour.
}

Can some one help me with this code?
when i tried to execute this..... it reads the string untill character
' a ' and copies to str.
after 'a' everything else we type is discarded.

Yes, that's what you've asked scanf() to do.
where can this be used?

Ideally nowhere.
how exactly it is working?

Implementation and platform specific. Ask in the appropriate group.
is it making ^ operation on read data

Not at all. scanf()'s ^ is totally different from the bitwise exclusive
OR operator.
and when 'a' is pressed the ^
operation value turns out to be 0 which is string termination. is it
so?

No, for heaven's sake, acquire almost any book on C and read it
through.
can i use other operators also instead of ^?

No, and in the context of scanf() ^ is not an operator.
 
S

Shhnwz.a

Hi,
This is way of using scanf is called selection parsing.
which means that .. scanf("%[parsing chars]",);

now important points to be noted and let us learn by examples-
1) scanf("%[abcdefjh]",str);
With this scanf will accept only these characters which are present
in its search list.
suppose if we input--> aejhxeb......so on.
result- here it will except only upto first illegal character is
encountered as per the searchlist.. so it willl accept
only..upto.."aejh" discarding all after that.

2) Now second way to use this search list technique called circumflex
method.
scanf("%[^abcdefjh]",str);
here the meaning is just reversed i.e it will accept all the
characters except those which are in the list.
suppose we input - xyzadayz..
result - here it will except only upto "xyz" becoz it
encounters 'a' which is illegal as per the search list

3) Comming to your queries.....
You have used the circmflex method now I think you understand it .
In printf it is not used.
for other datatypes it will work..but..be specific with your
Conversion Factors like.."%d...%s"..here we can see that no conversion
factors are being used which means that...it will work best for raw
types which is generally ASCII values..
So better to use it for string processing or only specific inputs you
required from the user..

now...here is a trick....scanf("%[^\n]",str); this will accept all the
keys....even space and tabs..also....expect..enter which willl
terminate it..and hence you can say that.....
from scanf you can also trap spacess.....

hope I answered your query...

shhnwz.a
 
T

Tor Rustad

santosh skrev:
vamshi wrote:
char str[20];
[...]
scanf("%[^a]",str);

scanf() is second only to gets() in being unsuited for string input.

scanf() can be difficult to use correctly for beginners,
OP's broken way can be fixed:

scanf("%19[^a]", str);

is "safe", since it will not overflow 'str'.

OP, might want to remove the end-of-record marker 'a', with:

scanf("%19[^a]", str);
getchar();

Furthermore, for robust code, the return value of scanf()
need to be checked (see below).
fgets() is better suited for this job.

Well, try to write this with fgets():

char line[81];
int n;

n = fscanf(stdin, "%80[^\n]%*[^\n]", line)
getchar(); /* throw away '\n' */

:)

Above is a safe and simple way to read the first 80
char's of a line with unknown lenght. For error-checking,
we have:

case n == 1: line has been scanned
case n == 0: empty, i.e. no characters before '\n'
case n == EOF: EOF or I/O error before '\n', check with feof()/ferror()


A function like CBFalconer's ggets(), (search the group for source), is
even better.

Well, IIRC, ggets() used malloc/realloc, which I usually hate.
Wouldn't use it for cases where I need robust code. The
point is that ggets() is a potential DoS [1] security hole, since
it will grab all available memory...

R.H. fgetdata() has a 'maxrecsize' parameter, which makes
it more robust, see:

http://users.powernet.co.uk/eton/c/fgetdata.html

Ideally nowhere.

I have used it and will continue to do so, for example:

fscanf(stdin,"%*[^\n]");

when I just want to "eat" until the end-of-line.
Implementation and platform specific. Ask in the appropriate group.

AFAIK, the usage of circumflex (^) in a scanlist is
well-defined, it's rather the usage of (-) which is
implementation specific.
 
P

prcdacster

vamshi said:
main()
{
char str[20];
printf("Enter a string: ");
scanf("%[^a]",str);
printf("%[^a]",str);
}

Can some one help me with this code?
when i tried to execute this..... it reads the string untill character
' a ' and copies to str.
after 'a' everything else we type is discarded.
where can this be used? how exactly it is working?
is it making ^ operation on read data and when 'a' is pressed the ^
operation value turns out to be 0 which is string termination. is it
so? can i use other operators also instead of ^?
will it work on int and other data types?
whats the use of %[^a] in printf?

Thanks in advance....
Vamshi.
 
R

Richard Heathfield

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

scanf() 32
question about scanf 11
about scanf() 2
question on assignment suppression in scanf 2
avoid newline scanf 6
scanf 2
Q for a source code in an exercise 1
Problem with scanf 7

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top