Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Помогите разобраться  (Прочитано 64882 раз)
0 Пользователей и 8 Гостей смотрят эту тему.
CENTNER
Гость
« : 05-10-2005 11:07 » 

Я в си новичек, попросили написать простейшую программу с использованием цикла while на нахождение количества букв в тексте Жаль
Вот написал что-то, естественно не компилится:

#include <stdio.h>
int main() {
char a[256]; //задаем массив (строку символов)
int i = 0; // задаем начальное количество символов
printf ("Введите строку\n");
scanf ("%lf", &a); // вводим нашу строку
gets (a); // вызываем символ(?)
while (a[i] !=0); // тело цикла
b++;                
printf ("Результат", b);
return 0;
}

проблема в том что нам дали мукулатуру, так вот в этой мукулатуре нет почти ничего из того что говорит преподаватель
он дал "общие рекомендации" из которых я и написал то что выше  Так больше нельзя...
+ есть несколько вопросов на которые он и сам не смог дать нормального ответа:
почему, например, тип char, а не int (short, long)? (по идее int ведь и обрабатывается быстрее и может может содержать большее по значению число)
Я так понял можно даже задать вещественный тип double?
Что лучше использовать вместо scanf? (он вроде не допускает пробелов?)
Что за функция puts? (ни в одной книжке не нашел (имеется также borland c++ Киммел. П.)

« Последнее редактирование: 22-04-2006 14:21 от Алексей1153 » Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 05-10-2005 11:46 » 

переменная b не объявлена. Ты уверен, что вызывая gets(a) ты делаешь, то что тебе надо. К тому же у тебя вечный цикл нарисовался. Огласи что ты хочешь сделать.
Записан

ещё один вопрос ...
CENTNER
Гость
« Ответ #2 : 05-10-2005 12:20 » 

Точно сорри

#include <stdio.h>
int main() {
char a[256]; //задаем массив (строку символов)
int i = 0; // задаем начальное количество символов
printf ("Введите строку\n");
scanf ("%lf", &a); // вводим нашу строку
gets (a); // вызываем символ(?)
while (a[i] !=0); // тело цикла
i++;                
printf ("Результат", i);
return 0;
}

Уверенности, увы, нет
Необходима программа подсчитывающая количество символов во введенной строке с использованием цикла while.
Не удевлюсь если все должно выглядеть по другому
« Последнее редактирование: 22-04-2006 14:22 от Алексей1153 » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 05-10-2005 12:38 » 


while (a[i] !=0); // тело цикла
i++;
}


попробуй так
while (a[i]) i++;

или (щас блесну :))) )

while (a[i++]);

в любом случае - у тебя была точка с запятой, то есть пустой цикл while
« Последнее редактирование: 22-04-2006 14:25 от Алексей1153 » Записан

nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 05-10-2005 13:06 » 

Еще один недачет я никак не пойму (я уже писал об этом). Зачем ты пишешь scanf, а затем, сразу же gets
Код:
scanf ("%lf", &a); // вводим нашу строку
gets (a); // вызываем символ(?)
эффект то получается один и тот же (gets(a) заносит строку введенную с клавиатуры в переменную а ), а пользователю прдется несколько раз вводить строку.
Записан

ещё один вопрос ...
kroum
Интересующийся

ua
Offline Offline

« Ответ #5 : 05-10-2005 15:53 » 

printf ("Введите строку\n");
scanf ("%lf", &a); // вводим нашу строку
gets (a); // вызываем символ(?)

1. Вместо
printf ("Введите строку\n");
можно использовать
puts("Введите строку");

Функция puts выводит на экран текст с переходом строки (не нужно в конце задавать '\n')

2. Так как необходимо определить количество введенных символов, предполагается ввод текстовой строки. В данном случае нужно использовать %s вместо %lf (у тебя scanf(%lf, &a))

3. Согласен с nikedeforest о ненужности gets(a);
То есть, используй что-то одно - либо gets, либо scanf

printf ("Результат", i);

4. scanf и gets считывают строку, то есть обязательно добавляют в конец признак о ее окончании ('\0'), пожтому нужно выводить i-1

5. В такой записи у тебя результатом выведется только "Результат". Необходимо указать, что нужно вывести значение (i-1):
printf ("Результат: %i", i-1);
« Последнее редактирование: 19-12-2007 21:55 от Алексей1153++ » Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 05-10-2005 16:18 » 

kroum наверное полностью довершил разбор ошибок Ага, можно тему закрывать:)
p.s.
Цитата
или (щас блесну )) )
while (a[i++]);
Алексей, это ты откуда узнал? ЗдОрово, я такую запись никогда не видел.
Записан

ещё один вопрос ...
CENTNER
Гость
« Ответ #7 : 05-10-2005 20:02 » 


Всем спасибо за помощь, вот немного подправил и добавил подсчет конкретного символа в строке:
#include <stdio.h>
main() {
char a[256];
int i = 0;
int j;
int k = 0;
puts ("Vvedite stroku");
gets(a);
while (a[i]!='\0'){
i++;
}
for (j=0; j<i; j++){
if (a[j] == 'a' || a[j]=='A'){
k++;
}
}
printf ("Kol-vo simvolov = %d\n",i);
printf ("Kol-vo A = %d\n", k);
Не совсем понимаю смысл этой фразы:
"scanf и gets считывают строку, то есть обязательно добавляют в конец признак о ее окончании ('\0'), пожтому нужно выводить i-1"?


« Последнее редактирование: 19-12-2007 21:57 от Алексей1153++ » Записан
Михалыч
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 06-10-2005 01:32 » 

kroum наверное полностью довершил разбор ошибок Ага, можно тему закрывать:)
p.s.
Цитата
или (щас блесну )) )
while (a[i++]);
Алексей, это ты откуда узнал? ЗдОрово, я такую запись никогда не видел.

Оригинально, но на мой взгляд вредно - бо не наглядно. Так гораздо понятнее, причем не только тому, кто написал, а любому.
while (a[i]!='\0'){
i++;
}

С, как и С++, позволяют сооружать море подобных "сокращенных" конструкций. Применять их, или нет - дело вкуса и принятых в конторе норм. Я бы не стал. Хотя иногда выглядит круто. Но видимо не более того.
« Последнее редактирование: 19-12-2007 21:58 от Алексей1153++ » Записан

Поживем - увидим... Доживем - узнаем... Выживу - учту  Улыбаюсь
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 06-10-2005 04:43 » 

...
Цитата
или (щас блесну )) )
while (a[i++]);
Алексей, это ты откуда узнал? ЗдОрово, я такую запись никогда не видел.

Оригинально, но на мой взгляд вредно - бо не наглядно. Так гораздо понятнее, причем не только тому, кто написал, а любому.
while (a[i]!='\0'){
i++;
}

Если уж совсем до конца разбираться, то два этих алгоритма вообще дают разный результат:
 - в случае while (a[i ]) { i++ };  длина строки равна i.
 - в случае while (a[i++]);  длина строки равна (i - 1).
« Последнее редактирование: 19-12-2007 22:01 от Алексей1153++ » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 06-10-2005 05:30 » 


Михалыч , абсолютно согласен - так вредно. Это я просто повыпендриваться решил :)

сам бы я записал так

while (a[i]!=0) i++;

а вот '\0' понятности не добавляет, суть - то же самое

Hooter , наоборот

1)
- в случае while (a[i]) { i++ };
   ----- тут не учитывается ноль (== len-1)

2)
 - в случае while (a[i++]); 
   ----- тут Учитывается ноль (== len)

nikedeforest,
> Алексей, это ты откуда узнал? ЗдОрово, я такую запись никогда не видел.

то есть как откуда? это си
« Последнее редактирование: 19-12-2007 22:02 от Алексей1153++ » Записан

Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 06-10-2005 06:03 » 

Hooter , наоборот

1)
- в случае while (a[i ]) { i++ };
   ----- тут не учитывается ноль (== len-1)

2)
 - в случае while (a[i++]); 
   ----- тут Учитывается ноль (== len)

1. Я говорил не о конкретном значении длины строки, а о том, что алгоритмы дают разный результат. Ты это только подтвердил.
2. В примере CENTNERа нужно как раз посчитать символы в строке, а не количество байт строки (вместе с нулем).
« Последнее редактирование: 19-12-2007 22:03 от Алексей1153++ » Записан
CENTNER
Гость
« Ответ #12 : 07-10-2005 18:00 » 

А каким образом можно написать калькулятор? Чтобы можно было, например, написать в строке 2+3 и он давал ответ?
вот что получается у меня:
#include <stdio.h>
main() {
double a,b,c;
int i;
puts ("vvedite 1 cifru i znak");
gets (a);
puts ("vvedite 2 cifru");
gets (b);
if (a(i) == '+') {
a+b=c;
}
else if (a(i) == '-') {
a-b=c;
}
else if (a(i) == '*') {
a*b=c;
}
else {
a/b=c;
}
printf ("otvet = %d\n",c);
}
но даже этот не работает:-(
как лучше сделать подскажите?
« Последнее редактирование: 19-12-2007 22:04 от Алексей1153++ » Записан
RXL
Технический
Администратор

Online Online
Пол: Мужской

WWW
« Ответ #13 : 07-10-2005 18:55 » 

CENTNER, процедура такая: разбери введеную строку на лексические состовляющие, проверь допустимость синтаксиса, переставь операции согласно приоритетам, выполни их последовательно.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
CENTNER
Гость
« Ответ #14 : 09-10-2005 20:50 » 

Вот написал кусочек:
#include <stdio.h>
main() {
char a;
char b;
char c;
char d;
int i;
puts ("vvedite 1 cifru");
scanf("%lf",&a);
puts ("vvedite znak");
scanf("%lf",&b);
puts ("vvedite 2 cifru");
scanf("%lf",&c);
if (b =='+') {
d = a + c;
}
printf ("otvet = %lf\n",d);
scanf("%lf",&a);
}
а в ответе всегда "0"  Жаль при любых числах с любым знаком)
Почему?
« Последнее редактирование: 19-12-2007 22:04 от Алексей1153++ » Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 10-10-2005 12:41 » new

Позволь тебя просветить, потому как ты не первый раз ошибаешься в этом. Ты объявил переменные a,b,c,d типа char -это значит, что для них выделено 1 байт. Что же делаешь ты? Ты пишешь
Цитата
scanf("%lf",&b);

%lf-это спецификатор формата функции scanf. %lf-предназначен для типа long double (если я не ошибаюсь, я всегда для double использую), который в несколько раз больше типа char. Для типа char тебе нужен либо %c - если в переменную заносится один символ (так в твоем случае), или %s- если заносится строка символов.
Во-ыторых тебе необходимо объявить переменные a, c и d типом double.
Вот что должно выйти:
Код:
#include <stdio.h>
main() {
double a;
char b;
double c;
double d;
int i;
puts ("vvedite 1 cifru");
scanf("%lf",&a);
puts ("vvedite znak");
scanf("%c",&b);
puts ("vvedite 2 cifru");
scanf("%lf",&c);
if (b =='+') {
d = a + c;
}
printf ("otvet = %lf\n",d);
scanf("%lf",&a);
}


Я не компилировал, поэтому 100% не даю, что нет других ошибок, но вроде в остальном все верно. Пиши, если не получится.
« Последнее редактирование: 19-12-2007 22:05 от Алексей1153++ » Записан

ещё один вопрос ...
CENTNER
Гость
« Ответ #16 : 10-10-2005 18:43 » 

Большое спасибо!
Теперь все заработало:
#include <stdio.h>
main() {
double a;
char b;
double c;
double d;
int i;
puts ("vvedite 1 cifru");
scanf("%lf",&a);
puts ("vvedite znak");
scanf("%s",&b);
puts ("vvedite 2 cifru");
scanf("%lf",&c);
if (b =='+') {
d = a + c;
}
else if (b =='-') {
d = a - c;
}
else if (b =='*') {
d = a * c;
}
else {
d = a / c;
}
printf ("otvet = %lf\n",d);
scanf("%lf",&a);
}
А можно ли реализовать ввод сразу (как я писал выше, т.е., например,  2+3), а не путем 3 последовательных действий?
Может есть способ указать программе числа до, и после определенного знака?
« Последнее редактирование: 19-12-2007 22:05 от Алексей1153++ » Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 10-10-2005 19:41 » 

Цитата
А можно ли реализовать ввод сразу (как я писал выше, т.е., например,  2+3), а не путем 3 последовательных действий?
Может есть способ указать программе числа до, и после определенного знака?
Считывай строку, пока не встретишь + или - или / или * - вот ты считал первое число, потом знак считаешь, ну и до конца последнее число считывай.
Записан

ещё один вопрос ...
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 11-10-2005 09:00 » 

Простейший способ это вот
Код:
double x, y;
char znak;
scanf("%lf%c%lf",&x,&znak,&y);
Только между цифрами и знаками пробел вводить нельзя. Но эту неприятность можно обойти.
Записан

ещё один вопрос ...
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 11-10-2005 09:21 » 

Код:
scanf("%lf %c %lf",&x,&znak,&y);
Теперь можешь вводить пробелы сколько захочешь. Проверено Улыбаюсь.
Записан

ещё один вопрос ...
CENTNER
Гость
« Ответ #20 : 12-10-2005 09:00 » 

В попытках создать версию выполняющую несколько действий сразу:
#include <stdio.h>
main() {
double x;
char znak;
double y;
double d;
double a;
puts ("Љ «мЄг«пв®а v 0.002 by Centner");
scanf("%lf %c %lf",&x,&znak,&y);
while (x!='\0' && y!='\0')
{
   if (znak =='+') {
   d = x + y;
   }
   else if (znak =='-') {
   d = x - y;
   }
   else if (znak =='*') {
   d = x * y;
   }
   else {
   d = x / y;
   }
   a = a + d;
}
printf ("®вўҐв %.2lf",a);
scanf("%lf",&x);
}
Прога компилится, но не работает должным образом Жаль
« Последнее редактирование: 19-12-2007 22:06 от Алексей1153++ » Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 12-10-2005 09:12 » 

Прога компилится, но не работает должным образом Жаль
"Должный образ" - это какой?
Какие данные ты вводишь? Что ожидаешь получить? Что на самом деле получаешь на выходе?
Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 12-10-2005 09:18 » 

Можно попытаться навскиду, но я не уверен, что првильно тебя понимаю:
...
double a;
...
   a = a + d;
Здесь налицо попытка использовать значение неинициализированной переменной.
Попробуй хотя бы double a = 0;

Непонятен смысл этого цикла.. Что ты хочешь получить в результате?
...
while (x!='\0' && y!='\0')
{
...
« Последнее редактирование: 19-12-2007 22:06 от Алексей1153++ » Записан
CENTNER
Гость
« Ответ #23 : 12-10-2005 09:38 » 

Из предыдущей версии калькулятора выполняющей действия с 2 числами, я хочу сделать версию выполняю щую несколько действий сразу (2+3*4/5и т.д)
Мне кажется что для этоно нужно включит основной алгоритм в цикл, который будет последовательно выполнять действия и добавлять соответствующие значения переменной "a" (a=a+d), а затем выводить ее как результат.
while (x!='\0' && y!='\0') - этим я попытался дать программе понять когда закончен ввод (честно говоря, сам не знаю как это сделать правильно, просто попробовал такой вариант)
Можно попытаться навскиду, но я не уверен, что првильно тебя понимаю:
...
double a;
...
   a = a + d;
Здесь налицо попытка использовать значение неинициализированной переменной.
Попробуй хотя бы double a = 0;
конечно нужен 0, я просто полагал что программа изначально присваивает нулевое значение переменной.
« Последнее редактирование: 19-12-2007 22:08 от Алексей1153++ » Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 12-10-2005 09:49 » 

Мне кажется что для этоно нужно включит основной алгоритм в цикл, который будет последовательно выполнять действия и
Одна из ошибок у тебя в том, что ты не включил scanf  в цикл.
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #25 : 12-10-2005 10:57 » 

Код:
puts ("Љ «мЄг«пв®а v 0.002 by Centner");
Это,я так пониаю, made in China Улыбаюсь
А если серьезно, был предмет у меня толи на втором, то ли на третьем курсе, назывался он "Лингвистика программного обеспечения САПР". Меня от этого предмета пучило по дикому (ну не нравился он мне). Так вот там мы изучали всякие синтаксические анализаторы и т.п.. Кажется сейчас становится задача сходная этому и меня начинает опять пучить Улыбаюсь.
Во-первых, как ты понимаешь, нужно что-то типа таблицы преоритетов. Как ты сейчас пишешь, так твой калькулятор наплюет на все законы математике. Стоит помнить, что умножение и деление производится раньше сложения и вычитания  и пр., у тебя этого нету.
Поэтому про должный образ ты правильно сказал. Здесь реализация чуток по сложнее будет и с наскока ты ее не возмешь.

 
Записан

ещё один вопрос ...
Alf
Гость
« Ответ #26 : 12-10-2005 11:27 » 

Калькулятор - это простейшая хрестоматийная задача, чуть сложнее "Hello, world".

Одно из возможных решений я привел здесь: https://club.shelek.ru/viewart.php?id=220

(Надеюсь, не забанят за рекламу).
Записан
CENTNER
Гость
« Ответ #27 : 12-10-2005 11:29 » 

2 Hooter включал
те-же грабли
дело еще в чем-то Жаль
« Последнее редактирование: 12-10-2005 11:45 от CENTNER » Записан
CENTNER
Гость
« Ответ #28 : 12-10-2005 11:45 » 

2 Alf - спасибо за статейку, как голова отойдет поробую вникнуть
2 nikedeforest - Про приоритеты я думал, хотел просто пока без них реализовать. в общем посижу, еще помучаюсь   :vzhik:
Записан
Hooter
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 12-10-2005 11:48 » 

включал
те-же грабли
дело еще в чем-то Жаль
дык что не получается конкретно?

Например, в твоей текущей реализации нельзя реализовать такое
версию выполняю щую несколько действий сразу (2+3*4/5и т.д)
У тебя получится только так: (2+3) + (4*5) + (6/7).

Попробуй почитать статью Alf'а - думаю, поможет.
« Последнее редактирование: 19-12-2007 22:08 от Алексей1153++ » Записан
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines