Программа C не будет печатать строку, уже пробовала сбросить

Программа должна получить имя и фамилию пользователя, а затем распечатать их как фамилию, имя. Программа останавливается сразу после второго ввода. Я попробовал fflush (stdout), но это не сработало (возможно, я сделал это неправильно).

#include "stdafx.h"
#include <iostream>
using namespace System;
using namespace std;

int main()
{ 
    char First[30], Last[30];

    printf("Please type in your First Name: ");
    scanf("%s",&First);
    fflush(stdout);

    printf("Please type in your Last Name: ");
    scanf("%s",&Last);

    printf("%s %s", Last, First);

    printf("pause");
    return 0;
}

person Victor Sandoval    schedule 16.02.2019    source источник
comment
Это не программа на Си. C не имеет iostream или пространств имен.   -  person n. 1.8e9-where's-my-share m.    schedule 16.02.2019
comment
Я изменил ваш тег C на C++. Не стесняйтесь отменить это и превратить это в вопрос с/относительно кода C.   -  person Yunnosch    schedule 16.02.2019
comment
Пожалуйста, объясните больше о уже опробованном сбросе. Где, как пробовал?   -  person Yunnosch    schedule 16.02.2019
comment
Вау, спасибо за быстрые ответы! Курс описывается как курс программирования на C, и учитель требовал от нас использования Microsoft Visual C++ 2010, поэтому я предполагаю, что нам пришлось использовать iostream и пространство имен, чтобы сделать код похожим на C.   -  person Victor Sandoval    schedule 16.02.2019
comment
Это звучит как визуальный студийизм. Если вы не создадите программу Visual Studio как консольную программу (есть несколько других, которые получат консоль). Тогда потоку типа stdout некуда идти, и вы никогда не увидите вывод. Поэтому проверьте тип проекта вашей визуальной студии, чтобы убедиться, что это консольное приложение.   -  person    schedule 16.02.2019
comment
Если у вас есть курс C, пишите на C, а не на чем-то, что вы не знаете, как это называется, что может быть похоже на C. Visual Studio поддерживает C, поэтому используйте его.   -  person n. 1.8e9-where's-my-share m.    schedule 16.02.2019


Ответы (3)


С++ версия вашей программы:

#include <iostream>
using namespace std;

int main()
{ 
  string first, last;

  cerr << "Please type in your First Name: ";
  if (! (cin >> firs))
    return -1;

  cerr << "Please type in your Last Name: ";
  if (! (cin >> last))
    return -1;

  cout << last << ' ' << first << endl;

  return 0;
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra i.cc
pi@raspberrypi:/tmp $ ./a.out
Please type in your First Name: aze
Please type in your Last Name: qsd
qsd aze
pi@raspberrypi:/tmp $ 

Я проверяю, что имена были введены (без EOF), я использую cerr, чтобы убедиться, что сообщения сброшены без записи endl


И версия C:

#include <stdio.h>

int main()
{ 
  char first[30], last[30];

  fprintf(stderr, "Please type in your First Name: ");
  if (scanf("%29s", first) != 1)
    return -1;

  fprintf(stderr, "Please type in your Last Name: ");
  if (scanf("%29s", last) != 1)
    return -1;

  printf("%s %s\n", last, first);

  return 0;
}

Компиляция и исполнение:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra i.c
pi@raspberrypi:/tmp $ ./a.out
Please type in your First Name: aze
Please type in your Last Name: qsd
qsd aze

Я ограничиваю размер в scanf, чтобы не записывать из массивов, я проверяю, что scanf смог прочитать имена, я также использую stderr чтобы обязательно сбросить сообщение, не написав '\n'

first и last являются массивами, бесполезно использовать '&' в scanf для указания их адреса


Обратите внимание, что эти версии не позволяют вводить составные имена с использованием пробелов, чтобы можно было прочитать всю строку.

person bruno    schedule 16.02.2019

Это помогает подумать о цели вызова fflush(). Есть ожидающие данные, которые вы хотите, чтобы пользователь видел, чтобы они знали, что вводить.

Рассмотрим первый запрос (printf, scanf, flush). printf() помещает данные в буфер. Затем scanf() считывает ответ пользователя. Flush() не будет выполняться до тех пор, пока пользователь что-нибудь не введет.

Эти три вызова в неправильном порядке. Я оставлю исправление этого в качестве упражнения для читателя.

Теперь рассмотрим следующий запрос (printf, scanf). printf() помещает данные в буфер. Функция scanf() считывает ответ пользователя, но пользователь еще не увидит подсказку «... Фамилия:».

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

Кстати, scanf() не защищает от переполнения массивов First[] и Last[]. Это не обязательно, чтобы ответить на ваш первоначальный вопрос, но я упоминаю об этом, потому что даже после того, как вы исправите код, он останется небезопасным.

person Mark    schedule 16.02.2019

fflush(stdout);, который у вас есть, не помогает, потому что это слишком рано в коде, поскольку это не помогает сбрасывать последние printfs. Вы также можете использовать \n для сброса. Но это может не сработать, если ваше устройство вывода не является интерактивным, например. перенаправляется в файл.

У вас также есть другая проблема со спецификаторами формата scanf(): First и Last, будучи массивами, распадаются на указатели при передаче в scanf. Значит, вы передаете в scanf неверный тип аргументов — просто удалите & из вызовов scanf.

Таким образом, ваша программа может быть просто:

#include <stdio.h>

int main(void)
{ 
    char First[30], Last[30];

    printf("Please type in your First Name: ");
    scanf("%s", First);
    fflush(stdout);

    printf("Please type in your Last Name: ");
    scanf("%s", Last);
    fflush(stdout);

    printf("%s %s\n", Last, First);
    fflush(stdout);

    getchar();
    return 0;
}

Все вызовы fflush(stdout) могут не понадобиться, если бы вы могли использовать \n во всех вызовах printf, потому что вы, вероятно, используете интерактивный терминал.

Если вы используете C++, вам действительно следует использовать iostream для ввода-вывода. Во всяком случае, scanf — это ужасно, имеет много проблем, и его следует избегать.

person P.P    schedule 16.02.2019