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

int main() {
    char a[100], b[100];
    char *ret;
    scanf("%[^\n]s", a);
    scanf("%[^\n]s", b);
    ret = strstr(a, b);
    if (ret != NULL)
        printf("its a substring");
    else
        printf("not a substring");
    return 0;
}

My aim was to check whether a substring is present in the parent string in the string or not. I learned about the strstr() function from here.

I have previously used %[^\n]s in my codes before and they worked well. But, in this case as soon as I hit return/enter after typing one string, the output is not a substring.

What is it that I am doing wrong?

Community
  • 1
  • 1
Karan Singh
  • 1,114
  • 1
  • 13
  • 30

2 Answers2

13

The first call to scanf() stops when it sees a newline ('\n') but it's still in the input stream. So, the second call fails immediately as it sees the (same) newline character.

You should always check the return value of scanf() calls for failure.

You can insert a getchar(); call in between the scanf() calls to consume the newline character. Or better use fgets() and handle the newline character.


This is how you could use fgets() in your code:

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

int main(void) {
     char a[100], b[100];
     char *ret;
     if (fgets(a, sizeof a, stdin) == NULL) {
        /* error handling */
     }

     a[strcspn(a, "\n")] = '\0';
     if (fgets(b, sizeof b, stdin) == NULL) {
       /* error handling */
     }

     b[strcspn(b, "\n")] = '\0';
     ret=strstr(a, b);
     if(ret!=NULL)
         printf("its a substring");
     else
         printf("not a substring");
     return 0; 
}
P.P
  • 117,907
  • 20
  • 175
  • 238
  • I was using fgets(), to solve a concatenation of strings question right before this question, but the problem was that the concatenation also had a newline character in between, so I switched to scanf. – Karan Singh Jan 29 '17 at 12:55
  • Also, how do I use getchar() to consume the newline character? – Karan Singh Jan 29 '17 at 12:55
  • `fgets()` approach is better. You can remove it using `strcspn()`: `a[strcspn(a, "\n")] = '\0';` and `b[strcspn(b, "\n")] = '\0';` after the calls to `fgets()` on `a` and `b`. – P.P Jan 29 '17 at 12:58
  • Do you have a reference to this for a beginner?Its very difficult to understand :/ – Karan Singh Jan 29 '17 at 12:59
  • @Karan what he said basically says `retrieve a string`, `search for the newline`, and `remove the newline`. –  Jan 29 '17 at 13:01
  • @KaranSingh You just have to read the documentation and do some examples to understand them better. I have updated the answer with how you could make use of `fgets()` and remove the newline character. – P.P Jan 29 '17 at 13:05
  • @MarkYisri Sorry, I have accidentally overwritten your edit suggestion (which is good) because I was editing at the same. – P.P Jan 29 '17 at 13:08
3

The scanf() format you use %[^\n] does not have a trailing s and you should provide the maximum number of characters to store into the destination array. Since the array has a size of 100, you should specify %99[^\n].

Furthermore, you must skip the newline between the 2 %99[^\n] otherwise the second conversion will fail since there would no characters different from \n to match.

Here is a simple correction using scanf(). usr has a good alternative using fgets() which is a simpler way to parse input:

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

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

    if (scanf("%99[^\n]%c%99[^\n]", a, &c, b) == 3 && c == '\n') {
        if (strstr(a, b))
            printf("its a substring\n");
        else
            printf("not a substring\n");
    }
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • can you explain the %99[^\n] part please? – Karan Singh Jan 29 '17 at 17:14
  • why are you omitting the 's' (the specifier for a string)? – Karan Singh Jan 29 '17 at 17:28
  • @KaranSingh: the `99` is the maximum number of characters to store into the array pointed to by the pointer argument (before the null terminator, so it is the buffer size - 1). – chqrlie Jan 29 '17 at 18:48
  • 1
    @KaranSingh: The `s` is an error: `%s` and `%[^\n]` are 2 different conversion specifiers. With your format string, `scanf()` tries to match an `s` after the end of the line and fails. – chqrlie Jan 29 '17 at 18:49