Сначала объяснение. Тогда несколько вариантов решения проблемы.
Проблема в том, что вы смешиваете линейно-ориентированный ввод (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 >> ...
) в одном и том же потоке - потому что они ВСЕ ЕЩЕ обрабатывают переводы строк по-разному.