如何在scanf函数中使用编辑转换代码以停止扫描特定单词的字符串

问题描述 投票:1回答:2

我想知道如何在scanf函数中使用编辑转换代码来停止扫描特定单词(如标题所示)的字符串。我对这最有可能的工作方式有所了解,但对我的意图却没有任何效果。

#include <stdio.h>  

int main(void) 
{ 
    char name[50]; 
    printf("Say your message: ");
    scanf("%[^ over]", name); 
    printf("Received message: %s\n", name);

    return 0;
}

这给了我以下输入为“我快要过去了”的输出]

/* 
Say your message: I'm almost there over
Received message: I'm
*/

我知道它正在做的是检查字符''((空格字符),'o','v','e'或'r'中的任何一个字符第一次出现在哪里,并在遇到任何一个字符时停止扫描这些字符。这就是为什么它在我结束时停下来,撞到空格字符并停止扫描的原因。

我不知道如何以输出“我快到了”的方式正确编写此代码。我知道绝对可以通过for循环来做到这一点,但是我想知道仅使用此方法怎么做。有人知道该怎么做吗?

c scanf
2个回答
0
投票

您不能单独使用scanf。您需要找到终止字符串,然后执行一些指针运算。

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

char *strrev(char *str) {
    if (!str || ! *str) return str;

    int i = strlen(str) - 1, j = 0;
    char ch;
    while (i > j) {
        ch = str[i];
        str[i] = str[j];
        str[j] = ch;
        i--;
        j++;
    }
    return str;
}

int main(void) 
{
    while(1) {
        char name[50];
        printf("Say your message: ");
        scanf("%49[^\n]", name);
        char c; while((c = getchar()) != '\n' && c != EOF);
        // flush input buffer (didn't consume \n)

        name[49] = '\0';
        char *e = NULL;

        printf("(1) Received message: `%s`\n", name);

        char delim[] = " over";
        strrev(name);
        strrev(delim);
        e = strstr(name, delim);
        int len = (e) ? strlen(name) - (int)(e-name) - strlen(delim) : strlen(name);
        strrev(name);
        printf("(2) Received message: `%.*s`\n", len, name);

        e = strstr(name, delim);
        if(e) *e = '\0';
        printf("(3) Received message: `%s`\n", name);
    }

    return 0;
}
Say your message: I'm coming over over.
(1) Received message: `I'm coming over over.`
(2) Received message: `I'm coming over`
(3) Received message: `I'm coming`
Say your message: I'm coming over?
(1) Received message: `I'm coming over?`
(2) Received message: `I'm coming`
(3) Received message: `I'm coming`
Say your message: I'm coming over? over
(1) Received message: `I'm coming over? over`
(2) Received message: `I'm coming over?`
(3) Received message: `I'm coming`

((1)是输入的字符串

%49[^\n]被使用,因为%s总是忽略空白,我们要保留它。它不会以nul终止字符串,因此我们保留了一个元素来执行此操作。

(2)我们向后搜索以获得overlast实例。 (由于[C​​0]是非标准的,所以是strrev from here。)当字符串实际上不包含strrev时,使用三进制运算符可防止出现问题。 strrstr仅显示字符串的前delim个字符。

((3)是输入的字符串,其中%.*s的第一个实例被nul终止符len替换。

这是完成任务的最简单方法之一。


0
投票

在scanf函数中使用编辑转换代码以停止扫描特定单词的字符串

尽管通常首选使用over作为输入,但是对'\0'的恶意/偷偷摸摸的使用并利用fgets()不会重复字母呢?

"%n"
© www.soinside.com 2019 - 2024. All rights reserved.