2017-02-05 18 views
1

Выполняя некоторые простые упражнения, у меня теперь есть огромное сомнение в отношении iostream и указателей.Передача указателя char на cin и cin.get()

Это в 2 несколько различных файлов, которые я сделал (они оба работают):

Файл 1 принимает входной сигнал, как «Меня зовут # Марко» и COUT печатает «MyNameIs»

int main(){ 
using namespace std; 
char* ch=new char[256]; 
int count=0; 
cout <<"Enter chars, # to quit:\n"; 
cin >> ch; 
while(*ch!='#'){ 
    cout << ch; 
    ++count; 
    cin >> ch; 
} 
cout << endl << count << " characters read\n"; 
return 0; 
} 

файла 2 получает тот же вход, как и раньше, но на этот раз соиЬ печатает пространства тоже:

int main(){ 
using namespace std; 
char* ch=new char[256]; 
int count=0; 
cout <<"Enter chars, # to quit:\n"; 
cin.get(*ch); 
while(*ch!='#'){ 
    cout << *ch; 
    ++count; 
    cin.get(*ch); 
} 
cout << endl << count << " characters read\n"; 
return 0; 
} 

То, что я не понимаю, почему во втором файле в строке 8, я должен написать «соиЬ < < * ch "вместо" cout < < ch "как в первом. В самом деле, если я использую «соиЬ < < ч» в файле 2, все это я получаю кучу случайных символов (символы взяты из адреса указателя я думаю)

ответ

1

В первом случае вы читаете C- стиль в ваш массив. Это означает, что cin читает строку символов за раз и сохраняет эту последовательность символов в ch, за которой следует завершающий нулевой символ \0. Когда вы запустите cout << ch, cout попытается распечатать всю строку, остановив ее при ударе по нулевому символу.

Во втором случае вы читаете одиночный символ и храните его в ch[0]. Когда вы запускаете cout << ch, cout считает, что ваш char* является строкой в ​​стиле C, и он пытается распечатать всю строку, останавливаясь только тогда, когда она попадает в нуль-символ. Символы после первого, вероятно, будут значениями мусора - что бы ни случилось в памяти. Это неопределенное поведение.

Обратите внимание, что в реальном коде вы должны проверить, что ваши чтения были успешными. Если ваша программа встречает EOF или недопустимый вход, ваш цикл будет работать вечно. Также cin >> ch имеет потенциал для переполнения буфера, если пользователь вводит слишком много символов. Лучше использовать std::string или версию cin.get, которая принимает аргумент размера потока.

Смежные вопросы