5

I want to read two long sentences from input using scanf() which are in two new lines.

Code:

int main() {
    char a[100], b[100];
    scanf("%[^\n]s", a);
    scanf("%[^\n]s", b);
    printf("%s\n%s", a, b);
}

Input:

she is beautiful
That is a flower

Output:

she is beautiful

The second input is not being read by the scanf() statement.

How to fix it?

BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70

3 Answers3

5

This needs a correct answer. If you insist on using scanf(), there's only one format string that is safe and will do what you want:

int main() {
    char a[100] = "";
    char b[100] = "";
    scanf("%99[^\n]%*c", a);
    scanf("%99[^\n]%*c", b);
    printf("%s\n%s", a, b);
}

In your original string, you had [^\n]s which is wrong, because [^\n] is a conversion specifier itself, matching anything except a newline. So there shouldn't be an s following it.

The next change is the 99 prepended. This ensures a maximum of 99 characters is converted -- plus one byte for the terminating 0, you have exactly the 100 characters available in your array. Without that, if the user enters more than 99 characters, your buffer would overflow.

The last change is to append %*c: %c will match any character, in this case the newline that is left after matching %[^\n]. But you're not interested in it, you just want to consume it. This is what the * is for, it discards the result of the matching.


If you can, just use fgets() like this, it is much simpler to use for this case:

int main() {
    char a[100] = "";
    char b[100] = "";
    fgets(a, 100, stdin);
    fgets(b, 100, stdin);

    // if needed, strip newlines, e.g. like this:
    size_t n = strlen(a);
    if (n && a[n-1] == '\n') a[--n] = 0;
    n = strlen(b);
    if (n && b[n-1] == '\n') b[--n] = 0;


    printf("%s\n%s", a, b);
}
  • What if there is a buffer overflow? The user inputs a string greater that 100 – Pushan Gupta Jun 07 '17 at 09:26
  • @VidorVistrom I think it's explained in my answer regarding `scanf()` and for `fgets()`, that's what the second parameter is for. –  Jun 07 '17 at 09:27
  • If a user inputs a value greater than 100 chars, it will automatically allocate it to the other variable.. 100 is for first variable. If 100 is exceeded including the null, the other variable will get the exceeding chars – Pushan Gupta Jun 07 '17 at 09:35
  • input this to your program aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa – Pushan Gupta Jun 07 '17 at 09:40
  • @VidorVistrom that would probably make a nice question. What you see as a result is not a *buffer overflow*, but the second call to `scanf()` or `fgets()` continuing to read where the first call stopped because there was no newline inside the limit of bytes to be read. For a robust program, you'd have to check whether you really have read a full line. This is possible, but outside the scope of *this* question. –  Jun 07 '17 at 09:49
  • Yes, this will happen. @VidorVistrom just so you can understand, here's a [version checking whether the line was complete](https://ideone.com/Cwjzg1). –  Jun 07 '17 at 10:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/146046/discussion-between-vidor-vistrom-and-felix-palmen). – Pushan Gupta Jun 07 '17 at 10:15
  • `scanf("%99[^\n]%*c", a);` is a problem if the first character read is a `'\n'`. `a` is not updated, `'\n'` remains in `stdin`. Also a problem with end-of-file and rare input error. – chux - Reinstate Monica Jun 07 '17 at 13:52
4

You could use fgets. And this could work for you.

#include <stdio.h>
#include <stdint.h>

int main() {
    char a[100], b[100];

    if (fgets(a, sizeof a, stdin) == NULL) {
        puts("fgets error");
        return -1;
    }

    if (fgets(b, sizeof b, stdin) == NULL) {   //Read blank lines 
        puts("fgets error");
        return -1;
    }

    if (fgets(b, sizeof b, stdin) == NULL) {
        puts("fgets error");
        return -1;
    }

    printf("%s\n%s", a, b);

    return 0;
}
Yunbin Liu
  • 1,484
  • 2
  • 11
  • 20
-1

Use like this

int main(){

    char a[100];

    while (scanf("%[^\n]%*c", a)==1) {
     printf("%s\n",a); 
    }
    return 0;
  }
Deb S
  • 509
  • 5
  • 16