T. Omasta
T. Omasta

Reputation: 36

Can I either input int or terminate scanf function?

Our task for school lesson is to input a number of integers. We don't know how many there will be.

I would like to know if there is a possibility to format scanf function that either stores integer or terminate itself by pressing enter.

Can I somehow put together scanf("%d") which only stores integers and scanf("%[^\n]) which terminates scanf function?

What I have known yet is that I cannot use scanf("%d%[^\n]) because scanf is waiting for that one integer, which I don't want to input because I already stored all integers I had to.

I don't really like a possibility to store string of all those integers into an array and then convert it to elements of another array with the exact numbers.

Upvotes: 2

Views: 606

Answers (2)

user3121023
user3121023

Reputation: 8286

Scan a character. Skip space and tab. Exit on newline.
Unget most recent character and try to scan an integer. If unable to scan an integer, scan and discard non-digit except space tab and newline.

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

int main ( void) {
    char i = '\0';
    int value = 0;
    int result = 0;

    printf ( "type number separated by space then enter\n");
    while ( 1 == scanf("%c",&i)) {//scan a character
        if ( ' ' == i || '\t' == i) {
            continue;
        }
        if ( i == '\n') {
            break;//newline so leave loop
        }
        ungetc ( i, stdin);//replace the character in input stream
        if ( 1 == ( result = scanf ( "%d", &value))) {
            printf ( " number entered as %d\n", value);
        }
        else {
            scanf ( "%*[^0-9 \t\n]");//clean non digits except space tab newline
            //or you could just break;
        }
    }
    return 0;
}

Upvotes: 1

dbush
dbush

Reputation: 223882

The scanf function is difficult to use correctly.

Instead, read a line at a time with fgets. If the entered string is just a newline, you exit the loop. If not, use strtol to parse the value. You'll know if just an integer was entered if the end pointer points to the newline at the end of the input.

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

int main()
{
    char line[100], *p;
    long val;

    while (fgets(line, sizeof(line), stdin)) {
        // if enter was pressed by itself, quit loop
        if (!strcmp(line, "\n")) {
            break;
        }

        errno = 0;
        val = strtol(line, &p, 10);
        if (errno) {
            perror("error reading value");
        } else if ((p != line) && (*p == '\n')) {
            // a valid integer was read
            printf("read value %ld\n", val);
        } else {
            // a non-integer was read or extra characters were entered
            printf("not a valid integer: %s", line);
        }
    }
    return 0;
}

Upvotes: 1

Related Questions