简体   繁体   中英

Line wise input in c

how can I enforce following input restriction in c?

First line contains float , Second line contains float , Third line int,

after pressing enter three times in console, program should be able to read each line and put the contents in respective int,int,float variables.

After three enter key press program should not wait for user input and start validation.

some test cases

line1: 34
line2:4
line3:12
result: ok

line1: 
line2:4
line3:12
result: not ok 

line1: Hi
line2:4
line3:12
result:  not ok 

so far I used the basics

    scanf("%f",&p);
    scanf("%f",&r);
    scanf("%d",&t);

it works fine for test case 1 and 3, but fails when I leave an empty line.

You should always check the return value of scanf .

The reason is that the return value is what scanf uses to communicate conversion errors, among other errors. For example, if your program tells scanf to expect a sequence of decimal digits, and scanf encounters something that doesn't match that pattern, the return value will indicate this failure.

The value returned will be the number of items that are successfully assigned to. For example,

char str[128];
int x, y = scanf("%d %127s", &x, str);

If y is 1, then it should be assumed that x is safe to use. If y is 2, then it should be assumed that both x and str are safe to use.

This answers part of your question. The next part is how you can go about ensuring that the input is in the form of lines . scanf doesn't strictly deal with lines ; it deals with other units, such as %d being an int encoded as a sequence of decimal digits (and a sign); it'll return once the decimal digit sequence ends... There's no guarantee that the decimal digits will occupy the entirety of the line .

There are actually two problems here: leading and trailing whitespace. All format specifiers, with the exception of [ , c , C , and n , will cause leading whitespace to be discarded. If you want to handle leading whitespace differently, you'll need to codify how you expect leading whitespace to be handled.

Consider that discarding user input is almost always (if not always) a bad idea. If you don't care what the remainder of the line contains, you could use something like scanf("%*[^\\n]"); getchar(); scanf("%*[^\\n]"); getchar(); to discard everything trailing up to and including the '\\n' newline character... The first statement would attempt to read as many non-newline characters as possible, and the second would discard the terminating newline character. However, if you want to ensure that the input occupies the entirety of the line, then you need to test the value returned by getchar .

An example using all of these considerations:

/* Test for leading whitespace (including newlines) */
int c = getchar();
if (c != '-' && !isdigit(c)) {
    /* Leading whitespace found */
}
ungetc(c);

/* Test for correct data conversion */
int x, y = scanf("%d", &x);
if (y != 1) {
    /* Something non-numeric was entered */
}

/* Test for trailing newline */
c = getchar();
if (c != '\n') {
    /* Trailing newline found */
}

Armed with this information, perhaps you can come up with an attempt and update your question with some code if you have any problems...

PS I noticed in the code you wrote, you seem to have %f and %d confused; %f is for reading into float s, and %d is for reading into int s, not the other way around...

As soon as I read line wise input , I know that fgets + sscanf must be used instead of direct scanf . Of course you can use getc / getchar as a workaround, but you can get corner cases, where I find fgets + sscanf cleaner. Example to get a float alone on a line:

char line[80], dummy[2];
float val;
if (fgets(line, sizeof(line), stdin) == NULL)... 
if (sscanf(line, "%f%1s", &val, dummy) != 1)...
// Ok val was alone on the line with optional ignored blanks before and/or after

You could also add a test for loooong lines :

if ((line[0] != 0) && (line[strlen(line)-1 != '\n'))...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM