在字符串inC中搜索空格

时间:2017-07-24 12:52:54

标签: c string whitespace scanf

问题是当我尝试输入一个带空格编译器的字符串渲染时,它是单独的2个字符串。但要求就是当字符串中有空格时,不要将其视为2个字符串,而是将其视为单个字符串。只有当我的四个输入是MAHIRL,CHITRA,DEVI和C时,程序才会打印出来。我的代码是:

#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;
}

我尝试使用strtok()和strpbrk(),但我不太确定如何在我的代码中实现它们。任何帮助或建议表示赞赏。感谢。

3 个答案:

答案 0 :(得分:5)

  

问题是当我尝试输入一个带空格编译器的字符串渲染为单独的2个字符串

这不是问题,scope :is_enabled, -> { where(enabled: true).joins(:theme).merge(Theme.is_enabled) } 格式说明符的 功能/行为%s。您无法使用它来读取以空格分隔的输入。

对于转换说明符scanf(),章节§7.21.6.2,C11

  

s匹配一系列非空白字符。 [...]

因此,匹配在遇到空格字符时就会结束,此处为s

如果您必须阅读(即输入由换行符终止),请改用fgets()

答案 1 :(得分:1)

%s指令在存储它们之前将字符与空格匹配,因此不可能以这种方式获取输入行。还有其他方法可以使用scanf()读取输入行,但这些方法容易出错,而且这对于这项工作来说真的不是正确的工具。

最好使用fgets()来获取缓冲区的输入行,并使用sscanf()来解析缓冲区。由于此处的要求是输入了四个字符串,因此使用此方法是一个简单的问题:

#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;
}

声明一个额外的字符数组buffer[],有足够的额外空间来包含额外的输入;这样,如果用户输入一些额外的字符,则不太可能干扰程序的后续行为。请注意,如果存在错误,fgets()将返回空指针,因此请检查;如果在此处遇到错误,则会打印一条错误消息并退出程序。

然后sscanf()用于解析buffer[]。请注意,最大宽度使用%s指令指定,以避免缓冲区溢出。 fgets()函数将换行符存储在buffer[]中(如果有空间),但以这种方式使用sscanf()可以避免需要进一步处理此换行符。

另请注意,sscanf()会返回成功分配的数量;如果此返回值不是4,则输入不符合预期,并且不应使用str1,...,str4保留的值。

更新

再次看这个问题,我不确定我是否真的回答了这个问题。起初我以为你想用scanf()来读取一行输入,然后从中提取字符串。但是你说:“只要字符串中有空格,就不要将其视为2个字符串”,即使示例代码中没有任何测试输入包含这样的空格。

将包含空格的用户输入读入字符串的一个选项是对每个字符串使用单独的fgets()调用。如果您将结果直接存储在str1,...,str4中,则需要删除由fgets()保留的换行符。可能更好的方法是将结果再次存储在buffer中,然后使用sscanf()来提取字符串,这次包括空格。这可以使用scanset指令完成:

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

此处的格式字符串包含一个前导空格,告诉sscanf()跳过零个或多个前导空白字符。 %[^\n]指令告诉sscanf()匹配字符,包括空格,直到遇到换行符,并将其存储在str1[]中。请注意,指定了最大宽度9,为\0终结符留出了空间。

如果您希望能够在用户输入的同一上输入多个字符串,每个字符串包含空格,则需要选择分隔符。选择一个逗号,可以通过以下方式完成:

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

这里有一个前导空格,可以跳过输入中可能存在的任何杂散空白字符(例如\n个字符)。 %[^,]指令告诉sscanf()匹配字符,直到遇到逗号,将它们存储在相应的数组中str1[],...,str3[])。以下,告诉sscanf()在下一个scanset指令之前匹配一个逗号和零个或多个空白字符。最终指令为%[^,\n],告诉sscanf()匹配字符,直到遇到逗号或换行符。

#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;
}

以下是与此最终计划的示例互动:

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

答案 2 :(得分:0)

从用户读取字符串时,请使用stdio_ext.h中的__fpurge(stdin)函数。这冲出了stdin。输入字符串时,最后按Enter键,这也是一个字符。为了避免这种情况,我们使用fpurge函数。

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

此外,如果要从包含空格的用户输入字符串,请使用以下命令:

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

这不会忽略输入字符串时输入的空格。

编辑:可以使用以下代码代替使用fpurge函数:

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