Извлечь часть входной строки с помощью scanf () - PullRequest
0 голосов
/ 17 октября 2019

Я задаю вопрос на этих двух примерах, в первой программе, когда я ввожу свое имя, она работает правильно:

#include <stdio.h>

int main ()
{
    char str [20];

    while(1)
    {
       printf ("Enter your name: ");
       scanf ("%19s",str);
       printf ("Your name is %s\n",str);
    }
    return 0;
}

Вывод:

Enter your name: Reza
Your name is Reza
Enter your name: 

Но в следующей программерезультат не соответствует ожидаемому:

#include <stdio.h>

int main ()
{
    char str [20];

    while(1)
    {
        printf ("Enter your name: ");
        scanf ("name=%19s",str);
        printf ("Your name is %s\n",str);
    }
    return 0;
}

При вводе name = Reza в качестве ввода программа неоднократно печатает вывод:

Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
Enter your name: Your name is Reza
...

По вашему мнениюв чем ошибка? Спасибо заранее

1 Ответ

2 голосов
/ 17 октября 2019

Это объясняется простой ссылкой на man scanf. В первом случае:

scanf ("%19s",str);

Спецификатор преобразования %s игнорирует начальные пробелы, поэтому '\n', оставшийся во входном буфере (stdin), используется незаметно.

В вашемвторой случай:

scanf ("name=%19s",str);

Вы строка формата ищет литерал "name=" в качестве части ввода, который, так как '\n', оставшийся после вашего предыдущего ввода, не используется, ошибка совпадения происходит потому, что на самом деле ваш ввод "\nname=...", извлечение символов прекращается в этой точке, оставляя символы во входном буфере непрочитанными, что приводит к одному и тому же сбою при каждом последующем вводе.

Вы можете решить эту проблему, включая пустое пространство в начале строки формата , в результате чего любой начальный пробел будет использоваться с:

scanf (" name=%19s",str);

Теперь вы можете ввести, например:

name=Gary
name=Tom
...

(конечно, у вас все еще будет проблема посторонних символов, если пользователь введет более 19 символов для любого имени - или если кошка случайно наступит на клавиатуре)

Вы также должны проверить возврат КАЖДОЙ используемой функции ввода - особенно scanf. Просто убедитесь, что число ожидаемых конверсий имеет место, например,

if (scanf (" name=%19s",str) != 1) {
    fputs ("error: conversion failed.\n", stderr);
    /* handle error */
}
...