简体   繁体   中英

Reading multiple lines of input with scanf()

Relevant code snippet:

char input [1024];

printf("Enter text. Press enter on blank line to exit.\n");
scanf("%[^\n]", input);

That will read the whole line up until the user hits [enter], preventing the user from entering a second line (if they wish).

To exit, they hit [enter] and then [enter] again. So I tried all sorts of while loops, for loops, and if statements around the scanf() involving the new line escape sequence but nothing seems to work.

Any ideas?

尝试这个:

while (1 == scanf("%[^\n]%*c", input)) { /* process input */ }

As was yet pointed out, fgets() is better here than scanf() .

You can read an entire line with fgets(input, 1024, stdin);
where stdin is the file associated to the standard input (keyboard).
The function fgets() reads every character from the keyboard up to the first new-line character: '\n' (obtained after pressing ENTER key, of course...).
Important: The character '\n' will be part of the array input .

Now, your next step is to verify if all the characters in the array input ,
from the first to the '\n', are blanks.
Besides, note that all the characters after the first '\n' in input are garbage, so you have not to check them.

Your program could be as follows:

char input[1024];
printf("Enter text. Press enter on blank line to exit.\n");
while (1) {
   if (fgets(input, 1024, stdin) == NULL)
     printf("Input Error...\n");
   else {
     /* Here we suppose the fgets() has reached a '\n' character... */
     for (char* s = input; (*s != '\n') && isspace(*s); s++)
        ; /* skipping blanks */
     if (*s == '\n')
        break; /* Blank line */
     else
        printf("%s\n", input); /* The input was not a blank line */
   }
}

That code must be written inside your main() block and,
more importantly, it is necessary to include the header <ctype.h> before all,
because the isspace() function is used.
The code is simple: the while is executed for ever , the user enter a line in each iteration, the if sentences checks if some error has happened.
If everything was fine, then a for(;;) statement is executed, which explores the array input to watch if there are just blanks there... or not.
The for iterations continue up to the first new-line '\n' is found, or well, a non-blank character appears.
When for terminates, it means that the last analyzed character, which is held in *s , is a newline (meaning that all earlier characters were blanks), or not (meaning that at least there is some non-blank character in input[] , so input is a normal text).

The "ethernal" while(1) is broken only in case that a blank-line is read (see the break statement in 11th line).

OP says "To exit, they hit [enter] and then [enter] again"

unsigned ConsecutiveEnterCount = 0;
for (;;) {
  char buffer[1024];
  if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
    break;  // handle error or EOF
  }
  if (buffer[0] == '\n') {
    ConsecutiveEnterCount++;
    if (ConsecutiveEnterCount >= 2 /* or 1, not clear on OP intent */) {
      break;
    }
  }
  else ConsecutiveEnterCount = 0;
  // Do stuff with buffer;
}
#include <stdio.h>
int main(){
    char arr[40];
    int i;
    for( i = 0; i < sizeof(arr); i +=2 ){
        scanf("%c%c",&arr[i],&arr[i+1]);
        if( arr[i] == '\n' && arr[i+1] == '\n' )
            break;
    }
    printf("%s", arr);
    return 0;    
}

... I tried all sorts of while loops, for loops, and if statements around the scanf() involving the new line escape sequence but nothing seems to work.

It seems you tried everything that you shouldn't have tried, prior to reading ! AC programmer is expected to read manuals lest they want to run into undefined behaviour which causes headaches like the one you've experienced. To elaborate, you can't learn C by guessing like you can Java.

Consider this your lesson. Stop guessing and start reading (the fscanf manual) !

According to that manual:

[ Matches a non-empty sequence of bytes from a set of expected bytes (the scanset).

The emphasis is mine. What you seem to be describing is an empty sequence of bytes, which means that the match fails . What does the manual say about matching failures ?

Upon successful completion, these functions shall return the number of successfully matched and assigned input items; this number can be zero in the event of an early matching failure . If the input ends before the first conversion (if any) has completed, and without a matching failure having occurred, EOF shall be returned. If an error occurs before the first conversion (if any) has completed, and without a matching failure having occurred, EOF shall be returned...

Again, the emphasis is mine... This is telling you that like most other C-standard functions, you need to check the return value ! For example, when you call fopen you then write some idiom along the lines of if (fp == NULL) { /* handle error */ } .

Where's your error handling? Note that the return value isn't merely a binary selection ; where n conversions are performed, there are n+2 possible return values in the range of: EOF , 0 .. n . You should understand what each of those means, before you try to use fscanf .

You can use following function when you want to read input from next line.

scanf("%d \n",&a);
scanf("%d \n",&b);
scanf("%d ",&c);

In case you are providing input from command line, it will take another input after line change.

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