Abhishek Thakur
Abhishek Thakur

Reputation: 23

Search whitespace in string inC

problem is when I try to enter a string with space compiler render that as separate 2 strings. But requirement is whenever there is a space in string don't treat it as 2 strings,but rather a single string. The program should print yes only if my four inputs are MAHIRL,CHITRA,DEVI and C. my code is:

#include<stdio.h>
#include<string.h>
int main()
{
    char str1[10],str2[10],str3[10],str4[10];
    scanf("%s",str1);
    scanf("%s",str2);
    scanf("%s",str3);
    scanf("%s",str4);
    if(strcmp(str1,"MAHIRL")==0 && strcmp(str2,"CHITRA")==0 && strcmp(str3,"DEVI")==0 && strcmp(str4,"C")==0 ){
        printf("yes");
    }
    else{
        printf("no");
    }
    return 0;
}

I tried using strtok() and strpbrk(), but I'm not quite sure how to implement them in my code. Any help or suggestion is appreciated. Thanks.

Upvotes: 0

Views: 395

Answers (3)

Raj Kumar Mishra
Raj Kumar Mishra

Reputation: 514

While reading strings from user, use __fpurge(stdin) function from stdio_ext.h. This flushes out the stdin. When you are entering a string, you press enter at last, which is also a character. In order to avoid that, we use fpurge function.

scanf("%s",str1);
__fpurge(stdin);
scanf("%s",str2);
__fpurge(stdin);
scanf("%s",str3);
__fpurge(stdin);
scanf("%s",str4);
__fpurge(stdin);

Also if you want to input a string from user containing spaces, use following:

scanf("%[^\n]", str1);

This will not ignore the spaces you enter while inputting string.

EDIT: Instead of using fpurge function, one can use following code:

while( getchar() != '\n' );

Upvotes: 0

ad absurdum
ad absurdum

Reputation: 21367

The %s directive matches characters up to a whitespace before storing them, so it is not possible to get lines of input this way. There are other ways to use scanf() to read lines of input, but these are error-prone, and this is really not the right tool for the job.

Better to use fgets() to fetch a line of input to a buffer, and sscanf() to parse the buffer. Since the requirement here is that four strings are entered, this is a simple problem using this method:

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

int main(void)
{
    char str1[10],str2[10],str3[10],str4[10];
    char buffer[100];

    if (fgets(buffer, sizeof buffer, stdin) == NULL) {
        fprintf(stderr, "Error in fgets()\n");
        return 1;
    }

    if (sscanf(buffer, "%9s%9s%9s%9s", str1, str2, str3, str4) == 4) {
        if (strcmp(str1,"MAHIRL") == 0 &&
            strcmp(str2,"CHITRA") == 0 &&
            strcmp(str3,"DEVI") == 0 &&
            strcmp(str4,"C") == 0 ){
            printf("yes\n");
        } else {
            printf("no\n");
        }
    } else {
        printf("Input requires 4 strings\n");
    }

    return 0;
}

An additional character array is declared, buffer[], with enough extra space to contain extra input; this way, if the user enters some extra characters, it is less likely to interfere with the subsequent behavior of the program. Note that fgets() returns a null pointer if there is an error, so this is checked for; an error message is printed and the program exits if an error is encountered here.

Then sscanf() is used to parse buffer[]. Note here that maximum widths are specified with the %s directives to avoid buffer overflow. The fgets() function stores the newline in buffer[] (if there is room), but using sscanf() in this way avoids needing to further handle this newline character.

Also note that sscanf() returns the number of successful assignments made; if this return value is not 4, the input was not as expected and the values held by str1,..., str4 should not be used.

Update

Looking at this question again, I am not sure that I have actually answered it. At first I thought that you wanted to use scanf() to read a line of input, and extract the strings from this. But you say: "whenever there is a space in string don't treat it as 2 strings", even though none of the test input in your example code contains such spaces.

One option for reading user input containing spaces into a string would be to use a separate call to fgets() for each string. If you store the results directly in str1,...,str4 you will need to remove the newline character kept by fgets(). What may be a better approach would be to store the results in buffer again, and then to use sscanf() to extract the string, this time including spaces. This can be done using the scanset directive:

fgets(buffer, sizeof buffer, stdin);
sscanf(buffer, " %9[^\n]", str1);

The format string here contains a leading space, telling sscanf() to skip over zero or more leading whitespace characters. The %[^\n] directive tells sscanf() to match characters, including spaces, until a newline is encountered, storing them in str1[]. Note that a maximum width of 9 is specified, leaving room for the \0 terminator.

If you want to be able to enter multiple strings, each containing spaces, on the same line of user input, you will need to choose a delimiter. Choosing a comma, this can be accomplished with:

fgets(buffer, sizeof buffer, stdin);
sscanf(buffer, " %9[^,], %9[^,], %9[^,], %9[^,\n]", str1, str2, str3, str4);

Here, there is a leading space as before, to skip over any stray whitespace characters (such as \n characters) that may be in the input. The %[^,] directives tell sscanf() to match characters until a comma is encountered, storing them in the appropriate array (str1[],..., str3[]). The following , tells sscanf() to match one comma and zero or more whitespace characters before the next scanset directive. The final directive is %[^,\n], telling sscanf() to match characters until either a comma or a newline are encountered.

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

int main(void)
{
    char str1[10],str2[10],str3[10],str4[10];
    char buffer[100];

    if (fgets(buffer, sizeof buffer, stdin) == NULL) {
        fprintf(stderr, "Error in fgets()\n");
        return 1;
    }

    /* Each individual string str1,..., str4 may contain spaces */
    if (sscanf(buffer, " %9[^,], %9[^,], %9[^,], %9[^,\n]",
               str1, str2, str3, str4) == 4) {
        if (strcmp(str1,"test 1") == 0 &&
            strcmp(str2,"test 2") == 0 &&
            strcmp(str3,"test 3") == 0 &&
            strcmp(str4,"test 4") == 0 ){
            printf("yes\n");
        } else {
            printf("no\n");
        }
    } else {
        printf("Input requires 4 comma-separated strings\n");
    }

    return 0;
}

Here is a sample interaction with this final program:

test 1, test 2, test 3, test 4
yes

Upvotes: 1

Sourav Ghosh
Sourav Ghosh

Reputation: 134356

problem is when I try to enter a string with space compiler render that as separate 2 strings

That's not a problem, that's the feature / behaviour of %s format specifier with scanf(). You cannot read space-delimited input using that.

For conversion specifier s, chapter §7.21.6.2, C11

s Matches a sequence of non-white-space characters. [...]

So, the matching ends as soon as it hits a white-space character, here, the space.

If you have to read a line (i.e., input terminated by newline), use fgets() instead.

Upvotes: 5

Related Questions