заполнение массива элементов типа сhar c помощью (функций getchar () и printf () даёт почему-то разные результаты)

Модератор: Модераторы разделов

Ответить
promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

заполнение массива элементов типа сhar c помощью

Сообщение promov »

Друзья! Спраздником всех! Вот программа. В ней заполнается массив элементов типа сhar и он же выводится.

Код: Выделить всё

 #include <stdio.h>
      int main () {
        char name [6];
        scanf ("%s", & name );
       printf ("%s\n", name);
        return 0;
      }
То есть если мы введём ab<Enter> то по окончании программы экран будет иметь такой вид:
ab
ab
Здесь_будет_курсор

Теперь другая программа.

Код: Выделить всё

#include <stdio.h>
      int main () {
       int i= 0;
       char s [6];

       for (i; ((int)(s [i]= getchar ()))!= EOF; ++i ) {
       }
       s [i]== '\символ_ноль';
       printf ("%s\n", s);
       return 0;
      }
В этой программе массив заполняется в цикле с помощью функции getchar (). Он прекращает заполняться по нажатии <ctrl+d>- для проверки, нажато <ctrl+d> или нет и создано условие ((int)(s [i]= getchar ()))!= EOF. И после заполнения массива cимвол '\символ_ноль' вводится вручную. То есть если мы нажмём ab'\n'<ctrl+d>, экран должен принять вид, как и тот, который бы он принял после выполнения первой программы. Но нет! Он принимает такой вид:
ab
ab
А_вот_здесь_должен_быть_курсор_но_здесь_не_курсор_а_какой-то_непонятный_знак_вопроса_а_то_и_не_один_ещё

Почему так? Создаётся впечатление будто символ '\символ_ноль',который мы ввели вручную, куда-то исчез! А в первой программе он никуда не исчезает и программа выводит предскзуемый результат. Не поможите ли разобраться? Спасибо.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
v04bvs
Сообщения: 636
ОС: Debian GNU/Linux

Re: заполнение массива элементов типа сhar c помощью

Сообщение v04bvs »

Код: Выделить всё

       s [i]== '\символ_ноль';


Здесь опечатка. Символ «=» должен быть в единственном экземпляре.

Кстати это:

Код: Выделить всё

((int)(s [i]= getchar ()))!= EOF

не портабельно. Сначала getchar() возвращает нам (int) -1, который преобразуется в (signed char) -1, потом мы это опять преобразуем в (int) -1 и сравниваем с EOF. А вот если на платформе char это unsigned char, то (int) -1 => (unsigned char) 255 => (int) 255 != (int) -1.
Спасибо сказали:
Аватара пользователя
Skladnoy
Сообщения: 90
ОС: Debian

Re: заполнение массива элементов типа сhar c помощью

Сообщение Skladnoy »

Код: Выделить всё

s [i] == '\символ_ноль';

Ошибка тут. Нужно = а не ==.

Кстати с -Wall gcc пишет варнинги: warning: statement with no effect
Спасибо сказали:
promov
Сообщения: 384
Статус: Участник
ОС: Debian GNU/Linux

Re: заполнение массива элементов типа сhar c помощью

Сообщение promov »

Парни, прошу прощения, сейчас по новой разбираться буду.
...Да, программа заработала, но она случайно заработала. Потому, что вот эта вот строка изначально неправильно написана (Напомню, переменная s объявлена как char)

Код: Выделить всё

 s [i]= getchar ()

Надо обязательно позаботиться о том, чтобы все значения, которые может вернутьgetchar () безусловно влезли в переменную s. Безусловно, а не случайно, как у меня. Потому-то и нужно объявить s как int. А я это с самого начала знал, но я хотел посмотреть: получится или не получится сэкономить место? Ведь у меня не одна переменная s, а их целый массив. Не получилось. Эх, а вот если бы эта запись была рабочая, получилось бы точно:

Код: Выделить всё

 (int) s [i]= getchar ()

То есть объявляем массив s элементов типа char, а потом всякий элемент приводим к типу int и на законных основаниях впихиваем в него -1, если таковая случается. Но нет. Нельзя перетипизированной переменной присваивать какое-либо значение. Я специально эксперементировал с различными вариантами. Не присваивается и всё тут. Так что и остаётся использовать тип int вместо char, 4 байта вместо одного...
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Спасибо сказали:
Аватара пользователя
Debris
Сообщения: 282
ОС: Debian GNU/Linux Lenny
Контактная информация:

Re: заполнение массива элементов типа сhar c помощью

Сообщение Debris »

promov, думаю 10-20 лишних байт в ваших учебных программах роли не сыграют, другое дело если бы вы писали что нибудь крупное и захватывали через нью скажем несколько десятков мегабайт. Не надо пока гнаться за байтами :) лучше поймите как оно работает.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: заполнение массива элементов типа сhar c помощью

Сообщение drBatty »

promov писал(а):
07.01.2008 21:57
То есть объявляем массив s элементов типа char, а потом всякий элемент приводим к типу int и на законных основаниях впихиваем в него -1
Гениально!!! Нобелевка ваша! Берём файл в 1000G читаем его как набор целых и пихаем на законных основаниях(закон promov-а) в массив char'ов в 250G(у меня в int 4 char). Это же супер архиватор!, применяя вторично это преобразование мы очень быстро сожмём любой файл в 4 байт(одно целое). Совет: используйте не эл-ты массива, а указатели:
char s[77];
char *ps = &s[35];
*((int*)ps) = getchar();
PS: супер разархиватор напишите сами, пожалуйста.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Ответить