Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Заполнение строкового массива в C++

Назар Обухов Знаток (410), закрыт 3 дня назад
Всем привет, начал в универе изучать С++, до этого изучал Python. На паре надо было решить простенькую на первый взгляд задачу, в которой нужно заполнить строковый массив с клавиатуры и потом как-то преобразовать. Вопрос в следующем: почему, когда размер массива задан заранее, программа работает хорошо и заполняет каждый элемент, а, когда размер массива я ввожу с клавы, происходит невесть что?Здесь размер n я задал заранее. Как видете, прога спокойно считала мой ввод с клавы и заполнила оба элемента.Но вот мне стоило начать вводить размер массива с клавы, так он начал пропускать первый элемент и выводить "Enter smth" два раза подряд. Помогите, пожалуйста.
Лучший ответ
Андрей Высший разум (461902) 3 дня назад
Потому, что после ввода числа с помощью >> в буфере ввода остаётся конец строки, который вводится первым getline. Это стандартные грабли во многих языках программирования. В Python же проблему обошли, разрешив вводить только строку целиком.

Можно сделать как в Python: использовать для ввода только getline и явно преобразовывать строки в числа.

Но если хочешь смешивать разные способы ввода, то между использованием >> и getline необходимо очищать входной буфер:
 cin >> n;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
https://ru.stackoverflow.com/questions/562229/Очистка-буфера-ввода-cin

P.S. Использовать в C++ массивы вида A[2] или A[n] - плохая идея. Полноценные массивы реализуются в языке стандартными классами array и vector.
Назар ОбуховЗнаток (410) 3 дня назад
Скажи, пожалуйста, какую библиотеку/предпроцессор ты используешь для команды cin.ignore(numeric_limits<streamsize>::max(), '\n'); ? У меня он ошибку выводит.
Андрей Высший разум (461902) Назар Обухов, Я же дал ссылку на stackoverflow, где это есть. Для *_limits подключается стандартный файл limits:
 #include <limits> 
Назар ОбуховЗнаток (410) 3 дня назад
Слушай, ещё такой вопрос: мою проблему можно решить, используя вместо cin команду scan_f? Или это ничего не поменяет?
Андрей Высший разум (461902) Назар Обухов, Со scanf будет точно такой же геморрой. Просто scanf - это низкоуровневый механизм языка C, а cin - высокоуровневый механизм языка С++. И при написании кода на C++ желательно максимально использовать высокоуровневые механизмы: чтобы минимизировать кол-во ошибок в коде, которые ни ты, ни компилятор не заметят.
Остальные ответы
Николай Веселуха Высший разум (369064) 3 дня назад
 #include <iostream> 
#include <string>

// Шаблоны для консольного ввода данных
constexpr std::streamsize MAX_LINGTH = 0x1000;
template<typename T>
T parse(const char* prompt) {
T value{};
std::cout << prompt;
std::cin >> value;
std::cin.ignore(MAX_LINGTH, '\n');
return value;
}
template<>
std::string parse(const char* prompt) {
std::string line;
std::cout << prompt;
std::getline(std::cin, line);
return line;
}
template<>
char* parse(const char* prompt) {
char line[MAX_LINGTH]{};
std::cout << prompt;
std::cin.getline(line, std::size(line));
return line;
}
// Конец шаблона

using namespace std;
int main() {
constexpr size_t buffer = 300;
string text[buffer];
auto count = parse<size_t>("Count: ");
for (size_t i = 0; i < count; ++i) {
text[i] = parse<string>("Line: ");
}
puts("Output string[]:");
for (const auto& line : text) {
if (line.empty()) break;
cout << line << '\n';
}
auto line = parse<char*>("Line: ");
cout << "Output char*: " << line << '\n';
auto integer = parse<int>("Integer: ");
cout << "Output integer: " << integer << '\n';
}
Похожие вопросы