scanf"tricks"

Z

Zach Echlin

Get the string from scanf and find the sup string using strstr. You can
then use atof to convert it to numbers.

char * strstr ( const char * string1, const char * string2 );
 
P

Przemo Drochomirecki

hi,
SCANF is not well described in my books, i'd like to do this stuff:
1) read all numbers from a line, separated by #32
2) read all numbers from a line, separaed by ','
3) read whole line

thx in adv.
 
A

alawi

to grab the entire line, you can use

char buffer[10000];
scanf("%[^\n]\n", buffer);

I know it's ugly to have a huge buffer lying around, but
I always have them when I have to do string manipulation
in C. I'm not completely certain that the %[...] conversion
is ANSI (but it works on my [linux] box). If it doesn't,
you can do this:

char buffer[10000], ch; int i;
for(i=0; i<10000 && (ch=getchar()) != EOF && ch != '\n'; i++)
buffer = ch;

I sure hope that the %[...] is available on your machine :)

(btw, if it isn't and you end up using this code to grab an
entire line, you might want to use similar code to grab the
integers instead of grabbing the line and using strstr:

#include <ctype.h>
#include <stdlib.h>
...
int numbers[10000], i, j=0;
char buffer[100], ch;
for(i=0; i<100 && (ch = getchar()) != EOF && ch != '\n'; i++) {
if(!isdigit() && i > 0) {
buffer = 0;
numbers[j++] = atoi(buffer);
i=0;
}
else buffer = ch;
}

Of course, you can change isdigit(ch) to ch == ',' if you don't
want ctype; likewise, you can change atoi to sscanf if you don't
want stdlib. If you know how many integers there will be, of course,
you can also make int numbers[...] smaller. You can also do dynamic
resizing of the array if you want to, but (unless you're on a nice
system) it can be a pain.)

-- alawi
 
A

Arthur J. O'Dwyer

hi, do you know how to do this:

int a[10000]; (nevermind, who cares:) )

while (NOT END OF LINE) scanf("%d",&a[i++]);
i don't know how to write (NOT END OF LINE) condition, so i hope there's
some trick with [^/...] syntax in scanf...

scanf(), unfortunately, is not Turing-complete. You can't
loop with it. [See this thread in c.l.c for more fun with scanf:]
http://groups.google.com/[email protected]
So just write exactly what you wrote above, in C.

int a[10000];
int c;
int i = 0;

while ((c = getchar()) != '\n' && c != EOF) {
ungetc(c, stdin);
scanf("%d", &a[i++]);
}

Or more opaquely as [UNTESTED CODE]

int a[10000];
char h;

while (scanf("%d%c", &a[i++], &h) == 2 && h != '\n')
continue;

which relies on the fact that "%d" skips whitespace and
"%c" does not. [Please don't use this code as it is; it's
terribly ugly and hard to read. In this particular case,
I'm all for the string-parsing solution. Much nicer.]
Note that both functions expect input of the form
"42 43 1 2487 28\n", and will break in slightly different
ways on bad inputs like "42 \n" and "43 44 45 crash!"

HTH,
-Arthur
 
B

Ben Peddell

alawi said:
char buffer[10000], ch; int i;
for(i=0; i<10000 && (ch=getchar()) != EOF && ch != '\n'; i++)
buffer = ch;


This is the same as:
char buffer[10000];
fgets (buffer, 10000, stdin);

you can then use strstr or sscanf to scan the string.

To the original poster - #32 represents space (\x20), doesn't it?

Perhaps (just put together, not tested):


#define BUFLEN 1000
#define NUMCOUNT 1000
char buffer[BUFLEN];
char dump[BUFLEN];
int nums[NUMCOUNT];
int i, j, p, nc;
fgets (buffer, BUFLEN, stdin);
for (i = 0, p = 0; i < NUMCOUNT && buffer[0] != 0 ; i++){
sscanf (buffer, "%d%n", &nums, &nc);
p = nc;
sscanf (&buffer[p], "%[^0-9\n]%n", dump, &nc);
p += nc;
for (j = 0; j < (BUFLEN - p); j++){
buffer[j] = buffer[j + p];
}
if (buffer[strlen(buffer) - 1] != '\n' && (! feof(stdin))){
/* We overwrite the Nul ('\0') */
fgets (&buffer[BUFLEN - p - 1)], p + 1, stdin);
}
p = 0;
}


Note: don't even think about replacing the fgets above with gets, unless
you want to have the danger of buffer overflows.
 
M

Mac

hi, do you know how to do this:

int a[10000]; (nevermind, who cares:) )

while (NOT END OF LINE) scanf("%d",&a[i++]);
i don't know how to write (NOT END OF LINE) condition, so i hope there's
some trick with [^/...] syntax in scanf...

:)

p.s. i know how to do the task w string conversion:)

I'm not quite sure what you are asking.

For an excellent tutorial on scanf() use google groups to search this
newsgroup for posts written by Dan Pop that have scanf in them.

To read a line with scanf, you can use a scanset.

int result;
char a[10000 + 1];

result = scanf("%10000[^\n]", a);

/* if result = 1, you have success. If result = EOF, end of file was
encountered. If result = 0, no string was read in (empty line) */

This is similar to using fgets, except fgets reads the \n into the string
and doesn't provide as much information in its return value.

To skip something with scanf, you can use the * flag.

For example, scanf("%*[^\n]") will skip a whole line except for the \n at
the end. It will return 0 unless EOF is encountered.

Mac
 
P

Przemo Drochomirecki

hi, do you know how to do this:

int a[10000]; (nevermind, who cares:) )

while (NOT END OF LINE) scanf("%d",&a[i++]);
i don't know how to write (NOT END OF LINE) condition, so i hope there's
some trick with [^/...] syntax in scanf...

:)

p.s. i know how to do the task w string conversion:)
 

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

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top