Переменная присваивается автоматически - PullRequest
0 голосов
/ 15 мая 2018

Я делал проект, который получает имена учеников, номера бросков и оценки и возвращает процент или оценку в соответствии с потребностями пользователя.Я сделал функцию, использующую цикл for, чтобы назначить детали (имя и т. Д.) Переменной, но во время изменения аргумента цикла for программа присваивала "" (null) первой переменной в исполняемой части.Я что-то здесь пропустил?

#include <iostream>
#include <stdio.h>

using namespace std;

class Data 
{
    public: 
    int Rno[3], phy[3], mat[3], chem[3];
    char name[3][100];

    void getInfo()
    {
        for(int i = 0; i < 3; i++)
        {
            cout << "Enter your name: ";
            gets(name[i]);

            cout << "Enter your Roll number: ";
            cin >> Rno[i];

            cout << "Enter your Physics marks: ";
            cin >> phy[i];

            cout << "Enter your Maths marks: ";
            cin >> mat[i];

            cout << "Enter your Chemistry marks: ";
            cin >> chem[i];
       }
    };
};

int main()
{
    Data d;

    d.getInfo();
    puts(d.name[1]);
}

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Сначала объяснение. Тогда несколько вариантов решения проблемы.

Проблема в том, что вы смешиваете линейно-ориентированный ввод (gets()) с отформатированным вводом (cin >> ....) на одном устройстве ввода / потоке.

Такие функции по-разному обрабатывают пробелы - особенно переводы строк. И из-за этого вы можете получить неожиданные взаимодействия. В этом случае cin >> chem[i] прочитает целое значение, остановится при обнаружении новой строки, оставит символ новой строки ожидающим чтения. Тогда gets() - в следующей итерации цикла - встретит новую строку и сразу же вернется (отсюда и «null», если использовать ваше описание).

OK; это объяснение. Что с этим делать?

Решение не состоит в том, чтобы смешивать такие стили ввода. Одна опция последовательно использует строчно-ориентированный ввод, чтобы читать ВСЕ как строку, а затем отдельно анализировать строку.

Некоторые люди предложат подходы, которые включают в себя отбрасывание (или «сброс») оскорбительных строк. Этот подход не работает, если ваш ввод сложен (например, много разных операторов читают из одного и того же потока по-разному), потому что необходимо гарантировать, что КАЖДЫЙ случайный перевод новой строки будет отброшен. Он также подвержен ошибкам - вы можете непреднамеренно отбросить ввод, который должна прочитать ваша программа.

Также избегайте использования gets() как чума. По какой-то причине он был удален из последних стандартов С - он небезопасен по своей природе.

Существуют различные способы использования потоков C ++ (например, cin) для безопасного чтения строк и других типов. Например, если some_str имеет тип std::string, тогда std::getline(std::cin, some_str) может использоваться для считывания полной строки ввода. std::getline() также имеет то преимущество, что может читать строку произвольного размера. Но, тем не менее, избегайте использования std::getline(cin, some_str) и потокового ввода (cin >> ...) в одном и том же потоке - потому что они ВСЕ ЕЩЕ обрабатывают переводы строк по-разному.

0 голосов
/ 15 мая 2018

Проблема с не промывкой cout.В вашем случае внутри цикла cout должен быть сброшен перед вызовом gets.

cout << "Enter your name: "<<endl;  // This cout should be flushed properly **with** new line character
gets(name[i]);

Из комментария @ProXicT

cout << "Enter your name: "<<flush;  // This cout should be flushed properly **without** new line character
    gets(name[i]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...