user7313260
user7313260

Reputation:

Why does the presence of `n` in the input sentence before `\n` give wrong output?

I want to input a sentence (containing any possible characters) and print it. But there is a catch. If there is a \n in the sentence then only the part of the sentence before \n should be printed out (i.e. \n should signify the end of the inputted sentence). I wrote a code for this situation :

#include <stdio.h>
main()
{
    char ch[100];
    printf("Enter a sentence");
    scanf("%99[^\\n]",&ch);
    printf("%s",ch);
}

This code seems to work fine but it fails in a certain situation. If there is the character n anywhere in the sentence before \n then it prints only the first word of the sentence! Why does this happen? How can I fix this bug?

This case works fine: enter image description here

But in this case it fails:

enter image description here


Detail from comments:

Q: Do you want to to stop at a newline, or at a backslash followed by n?
A: slash followed by n

Upvotes: 1

Views: 107

Answers (2)

chux
chux

Reputation: 153517

OP's calcification negated the first part of this answer.


OP has not formed the desired scan set for the "%[...]" specifier.

"%99[^\\n]" accepts any character except '\\' and 'n'.

Certainly OP wants "%99[^\n]". \\ changed to \ to accept any character except '\n'.


Yet I would like to take the goal up a bit. This part is only for pedantic code.

input a sentence (containing any possible characters)

How would code handle this if the null character '\0' was included in that "any possible character"?

Note that inputting a null character is not often easy from a keyboard.

Interestingly "%99[^\n]" will scan up to 99 characters (except a '\n') including the null character. Yet the below code prints ch as it it were a string and not a general array of characters.

#include <stdio.h>
int main(void) {
    char ch[100];
    printf("Enter a sentence\n");
    if (scanf("%99[^\n]", ch) != 1) {
      ch[0] = '\0';  // Handle a line of only `'\n``, EOF, or error
    }
    printf("%s",ch);
}

To accomplish this esoteric goal with scanf() (not the best tool in the shed), record the length of the scan and then print the array.

int main(void) {
    char ch[100];
    int n;
    printf("Enter a sentence\n");

    if (scanf("%99[^\n]%n", ch, &n) != 1) {
      n = 0; // If scanning stopped right away, set length `n` to 0
    }
    // Write as an array
    fwrite(ch, sizeof ch[0], n, stdout);
}

Upvotes: 1

user2371524
user2371524

Reputation:

The [] conversion specifier of scanf() works by defining an accepted (or, with ^, rejected) set of characters. So %[^\\n] will stop scanning at the first \ or the first n -> You can't solve your problem with scanf().

You should just read a line of input with fgets() and search for an occurence of "\\n" with strstr().


Side note: there's an error in your program:

char ch[100];
scanf("%99[^\\n]",&ch);

ch evaluates as a pointer to the first element of the array (so, would be fine as parameter for scanf()), while &ch evaluates to a pointer to the array, which is not what scanf() expects.

(the difference is in the type, the address will be the same)

Upvotes: 2

Related Questions