Страница 1 из 1

Помогите с С++ (пара вопросов)

Добавлено: Вс июн 26, 2005 10:13
Стэлла
В общем горю!!! Через 3 дня экзамен, нужно научиться писать самые простейшие программки с текстами. Вот, например, сама попробовала - заменить в тексте + на -:
#include <stdio.h>
void main ()
{ int c;
printf ("vvedite text\n");
c=getchar ();
while (c!=EOF) {
if (c=='+')
c='-';
putchar (c); }
c=getchar (); }
Программа, конечно не работает, т.к. писала я ее без особого понимания... Только вот в чем ошибка?

А еще сложности с программами на подсчет символов - посчитать сколько в тексте содержится цифр:
#include <stdio.h>
#include <conio.h>

int kol=0 ,i;
char c[50];


void main()
{

printf("vvedite stroku:\n");
gets(c);

i=0;
while(c!=EOF)
{
if((c>='0')&&(c<='9'))
{
kol++;
i++;
}
else i++;

}
printf("%d",kol);
}
тоже не работает :( Пожалуйста, скажите где у меня ошибки? :?
ЗЫ Среда Borland c++ 3.11, компилятор под дос (если что)

Добавлено: Вс июн 26, 2005 11:51
Ваганыч
вот изменил твои проги:
========

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

#include <stdio.h>

void main(){

	int c;

	printf ("vvedite text\n");

	while ((c=getchar())!='\n') {
		if (c=='+')	c='-';
		putchar (c);
	}

	c=getchar ();
}
===============

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

#include <stdio.h>
#include <conio.h>

int kol=0 ,i;
int c;


void main(){

	printf("vvedite stroku:\n");

	while((c=getchar())!='\n'){
		if((c>='0')&&(c<='9'))	kol++;
	}
printf("%d",kol);
c=getchar();
}
=============

[off]добавлено спустя 13 минут:[/off]

а теперь что в твоем коде было неправильно?
данная конструкция неправильно:

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

c=getchar ();
while (c!=EOF) {
   if (c=='+')  c='-';
   putchar (c);
} 
функция getchar() считывает только один символ из введенной строки. И если этот символ не есть EOF, то цикл зацикливается, что у меня и произошло. Если поместить getchar() в цикл, то он будет считывать по очереди все символы, что ты вводишь. И проверять равенство надо не на EOF(символ конца файла), а на '\n'(перенос/конец строки). Вот собственно и все.
Вторая прога:
ты написала полностью правильно, вот только вот тут:

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

while(c[i]!=EOF)
сравнивать надо опять же не с EOF, а с символом переноса строки('\n'). Хотя мой вариант 2ой проги, по-моему, компактнее :)

Добавлено: Вс июн 26, 2005 12:08
Fialka
Я уже подзабылa С++, но всё же мне казалось, что EOF используется для работы с файлами, а не при вводе с консоли. Какие хоть ошибки программа выдаёт?

Добавлено: Вс июн 26, 2005 14:21
glukoza
[off]Ваганыч,я дурею от тебя :)[/off]
Ваганыч писал(а):сравнивать надо опять же не с EOF, а с символом переноса строки('\n'). Хотя мой вариант 2ой проги, по-моему, компактнее
Можно и с EOF:

while( ( c = getchar() ) != EOF )
putchar(c);

Но тогда завершать ввод в эту утилиту придется Ctrl-D в юниксе и Ctrl-Z (кажется) в виндах, а не Enterом.

conio.h - в газенваген. Не портабельна никуда из MS-DOS, а то и с борландовских компиляторов (которым тоже место в газенвагене). Правильные компиляторы - Microsoft CL - тот, что дают с Вижуал Студией и с SDK/DDK, и gcc.

Добавлено: Вс июн 26, 2005 18:49
Ваганыч
glukoza,
Ну, во-первых, я согласен, что можно проверять и с EOF. ТУт все зависит от поставленной задачи. Если сравнивать строку, то с '\n', а если многострочный текст,то с EOF. Девушке я так понимаю надо сравнить строку(если бы текст, то она бы не спрашивала почему не работает ее 2ая прога).

насчет conio.h и компиляторов. Были поставлены конкретный условия: "Среда Borland c++ 3.11, компилятор под дос" В таком случае я не виже причин, по которым не могу юзать conio.h . Хотя в общем насчет борландских 16 разрядных компиляторов я с тобой согласен.

Добавлено: Вс июн 26, 2005 20:26
Gladiator
Ваганыч писал(а):Если сравнивать строку, то с '\n', а если многострочный текст,то с EOF
'\n' - есть совершенно обычный вводимый символ (или два, в зависимости от соглашений). EOF - физический конец входного потока. В этом принципиальная разница.

Добавлено: Вс июн 26, 2005 20:32
Ваганыч
'\n' - есть совершенно обычный вводимый символ (или два, в зависимости от соглашений). EOF - физический конец входного потока. В этом принципиальная разница.
Я знаю. Ну и что?

Добавлено: Вс июн 26, 2005 20:57
Gladiator
Ничего. Любой символ может по "усмотрению" программы закончить ввод. EOF его закончит независимо от "усмотрений" программы. В этом принципиальная техническая разница. Если вы не проверите на EOF, а он придёт, то программа некорректно завершится при попытке читать следующий символ. ;)

Добавлено: Вс июн 26, 2005 21:23
Ваганыч
Если вы не проверите на EOF, а он придёт, то программа некорректно завершится при попытке читать следующий символ.
OK. Тогда добавляем проверку на EOF.

Добавлено: Вс июн 26, 2005 21:46
glukoza
Gladiator
EOF как возвращаемое значение getchar() у нас "шире", чем символ - там тип int, а не char, именно за тем, чтобы уместился EOF. Он там (вроде как) -1, в то время как все осмысленные символы в диапазоне [0..255]

Значение EOF генерится C runtime ( getchar() и ее внутренностями ) искусственно.

Если читать как read(0, buf, len) - то никакого значения EOF не будет, а будет возврат нуля из read()

Добавлено: Вс июн 26, 2005 21:47
Gladiator
glukoza,не умничай. Мыслить надо высоко и абстрактно. :D

EOF - логическое понятие, символизирующее наступление физического конца входного потока. Чему он конкретно равен - зависит от природа обрабатываемого входного потока и операционной системы.

Добавлено: Вс июн 26, 2005 22:31
glukoza
Gladiator писал(а):Мыслить надо высоко и абстрактно
Начинающим - да, а "продолжающий" знает все эти абстракции наизусть, а еще знает, что devil is in the details.

Добавлено: Вс июн 26, 2005 22:58
Gladiator
Фик. :) Опытный чел запоминанием такой ерунды не парится. Потому как количество фактов бесконечно. А начинающий в принципе не способен так мыслить, потому как видел всего лишь одну ОС и одну архитектуру. Так мыслит только опытный "продолжающий". Он уже знает, что весь этот "дьявол в деталях" очень важен, но легко достаётся из справочников. А вот концептуальное понимание принципов, легко возмещает сиюмоментное незнание некоторых мелких фактов. :)

Добавлено: Пн июн 27, 2005 09:43
glukoza
Gladiator писал(а):Опытный чел запоминанием такой ерунды не парится
Точнее - человек с небольшим, но ненулевым опытом.

Есть как бы три стадии. Чайник, вот такой вот человек и опытый. То, о чем ты - это вторая стадия.
Gladiator писал(а):А начинающий в принципе не способен так мыслить, потому как видел всего лишь одну ОС и одну архитектуру.
Этого хватит для кучи реальных задач. Зайди на rsdn.ru и посмотри, у какого количества народу руки заточены только под Visual Studio - т.е. связку винды+MFC+визарды из Студии. Они даже не знают, где кончаются винды и начинаются MFC. Про портабельность - я молчу.
И ничего. Многие задачи решают на ура.
Gladiator писал(а):Он уже знает, что весь этот "дьявол в деталях" очень важен, но легко достаётся из справочников
Реальная работа по правке багов - в основном такие "детали". Проще писать сразу правильно :) а не лазить в справочники потом.
Gladiator писал(а):А вот концептуальное понимание принципов, легко возмещает сиюмоментное незнание некоторых мелких фактов.
Нет. Концепции - это просто. Достаточно просто. Если не обращать внимание на детали - то будет а) овердизайн в пару раз б) хреново с производительностью.

Плавали. Знаем.

Добавлено: Пн июн 27, 2005 10:30
Стэлла
Ваганыч,спасибо я разобралась!

Добавлено: Пн июн 27, 2005 10:52
Gladiator
Нет. Концепции - это просто. Достаточно просто.
---------------------------------------------------------------------
Неа. Хорошие концепции это оч сложно. Но не всегда видно сразу. :)

Добавлено: Пн июн 27, 2005 16:02
glukoza
Gladiator писал(а):Хорошие концепции это оч сложно
Достаточно прочитать 1-2 классических книжки и примеры хорошего в этом смысле кода.