Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.02.2012, 23:51   #1
ol-k_34
Пользователь
 
Регистрация: 08.02.2012
Сообщений: 31
По умолчанию Первые трудности с программированием на C

Привет. Я начала изучать C. Возникли первые трудности. Задание:напишите программу для вывода входного потока по одному слову в строке. Буду очень признательна, если поможете и объясните. Заранее спасибо..
ol-k_34 вне форума Ответить с цитированием
Старый 09.02.2012, 01:31   #2
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

http://programmersforum.ru/showthread.php?t=34061
_Bers вне форума Ответить с цитированием
Старый 09.02.2012, 17:59   #3
ol-k_34
Пользователь
 
Регистрация: 08.02.2012
Сообщений: 31
По умолчанию

Хорошо...вот код..пыталась что-то сделать...но это явно не правильно...не знаю как задать условие чтобы каждое слово выводил в строку (не судите строго, я только начала учить):

Код:
#include <stdio.h>

#define in 1
#define out 0

main()
{ int c,nl,state;

while((c=getchar())!=EOF){

      if(c==' '||c=='\t'||c=='\n')
      {state=out;}
      else if(state==out){state=in;}
      if(c=='\n'){
        putchar(c);}


    }
putchar(c);
           }

Последний раз редактировалось ACE Valery; 13.02.2012 в 17:58.
ol-k_34 вне форума Ответить с цитированием
Старый 10.02.2012, 20:52   #4
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Есть несколько способов решения.

Первый способ:
Если мы договоримся, что входной поток это строка, состаящая из слов, то пойдёт и так:
Код:
#include <stdio.h>

#define SBUF 100

int main ()
{
    char buf[SBUF];
    while (scanf("%s", buf) != EOF) {
        printf("%s\n", buf);
    }
}
Второй способ:
Если нашей программе будет перенаправляться файл cо множеством строк, вот так:
prog < file
То тут надо будет двигаться, как вы начали. То есть понять, как работает программа из K&R по подсчёту слов, символов, строк и переработать эту программу для выполнения упражнения. Я думаю, авторы этого добивались.

Точно ли вы разобрались, как работает программа по подсчёту слов, символов, строк? Если нет спрашивайте, что непонятно.

Вот вам мой вариант алгаритма, описанного с помощью ДРАКОН-схемы:



Код:
#include <stdio.h>

#define IN 1
#define OUT 0

int main ()
{
    int c, state;
    state = OUT;

    // считывание символов, пока не EOF (End Of File)
    while ((c = getchar()) != EOF) {
        // считанный символ - это символ пустого пространства ('\t', '\n', ' ')?
        if (c == '\t' || c == '\n' || c == ' ') {
            // предыдущее состояние - внутри слова?
            if (state == IN) {
                // печатаем переход на следующую строку
                putchar('\n');
                // запоминаем, что мы снаружи слова (state = OUT)
                state = OUT;
            }
        }
        else {
            // запоминаем, что мы внутри слова (state = IN)
            state = IN;
            // печатаем символ
            putchar(c);

        }
    }
}
P.S. Если подключить #include <ctype.h>, то можно использовать:
Код:
if (isspace(c))
Вместо:
Код:
if (c == '\t' || c == '\n' || c == ' ')
(см. приложение Б, раздел 2 этого приложения)

Последний раз редактировалось 8Observer8; 10.02.2012 в 21:10.
8Observer8 вне форума Ответить с цитированием
Старый 10.02.2012, 21:14   #5
ol-k_34
Пользователь
 
Регистрация: 08.02.2012
Сообщений: 31
По умолчанию

Вроде разобралась (я по поводу подсчета слов). Вот код программы:
Код:
#include <stdio.h>

#define IN 1
#define OUT 0

main()
{
   int c,nl,nw,nc,state;

   state=OUT;
   nl=nw=nc=0;
   while((c=getchar())!=EOF) {
          ++nc;
          if(c=='\n')
             ++nl;
          if(c==' '||c=='\n'||c=='\t')
             state=OUT;
          else if(state==OUT) {
             state=IN;
             ++nw;
            }
        }
        printf("%d %d %d\n",nl,nw,nc);
    }
Едиснтвенное я не поняла, где идет условие что это есть слово...

Код:
 if(c==' '||c=='\n'||c=='\t')
             state=OUT;
          else if(state==OUT) {
             state=IN;
             ++nw;
"...иначе, если state равно OUT, то state=IN".почему равно OUT не понимаю.

Последний раз редактировалось ACE Valery; 13.02.2012 в 17:59.
ol-k_34 вне форума Ответить с цитированием
Старый 10.02.2012, 21:17   #6
ol-k_34
Пользователь
 
Регистрация: 08.02.2012
Сообщений: 31
По умолчанию

Но я еще маленько разбиралась и написала так:

Код:
#include <stdio.h>

#define in 1
#define out 0

main()
{ int c,state;
 state=out;

while((c=getchar())!=EOF){

      if(c==' '||c=='\t'||c=='\n')
          state=out;
      else if(state==out){
          state=in;}

    for(c>1;c=getchar();c!=EOF){

      if(c==' ')
          {c='\n';
          putchar(c);
          c=getchar();}
          }

    }


}


Только слова он не выводит...

Кстати, спасибо за помощь..

Последний раз редактировалось ACE Valery; 13.02.2012 в 17:59.
ol-k_34 вне форума Ответить с цитированием
Старый 10.02.2012, 21:49   #7
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Цитата:
Сообщение от ol-k_34 Посмотреть сообщение
Едиснтвенное я не поняла, где идет условие что это есть слово...

if(c==' '||c=='\n'||c=='\t')
state=OUT;
else if(state==OUT) {
state=IN;
++nw;
"...иначе, если state равно OUT, то state=IN".почему равно OUT не понимаю.
Ключевой момент: state показывает предыдущее состояние (предыдущий символ был символом пустого пространства или нет), а текущий считанный символ показывает текущее состояние (текущий символ - это символ пустого пространства или нет)

Цитата:
Сообщение от ol-k_34 Посмотреть сообщение
if(c==' '||c=='\n'||c=='\t')
state=OUT;
else if(state==OUT) {
state=IN;
++nw;
Часть кода выделенная красным "сработает", когда текущий символ (текущее состояние) не символ пустого пространства, а если к тому же предыдущее состояние OUT (т.е. предыдущий символ был к примеру пробелом), то следовательно этот символ - это начало слова (пусть даже и одной буквы). И мы смело можем увеличить счётчик на единицу (++nw) И запомним состояние IN. Продолжаем...

Дальше интереснее. Если мы считаем опять символ, то код выделенный красным сработает по-другому. state теперь равен IN и счётчик не инкриминируется. И в самом деле зачем, если мы уже учли это слово.
8Observer8 вне форума Ответить с цитированием
Старый 10.02.2012, 22:15   #8
ol-k_34
Пользователь
 
Регистрация: 08.02.2012
Сообщений: 31
По умолчанию

Конечно, первый способ он короче и понятнее, если знать функции. Но я еще до этого момента не дошла =). Посмотрела ваш алгоритм. Вот давно мучил вопрос с EOF. У вас написано: считанный символ-это конец файла(EOF)? Как понять считанный символ есть конец файла? Т.е. мы вводим поток символов в строку и символ, который есть последний символ является концом потока символов, ну и строки тоже??? правильно?
ol-k_34 вне форума Ответить с цитированием
Старый 11.02.2012, 10:21   #9
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Договоримся, что у нас ASCII кодировка, а не UNICOD. ASCI-символ - это один байт (UNICOD- 2 байта, мы его пока рассматривать не будем). В файле хранятся не сами символы, а их ASCII-коды. Вот таблица всех ASCII символов --> ссылка.

Создайте файл и напишем в файле что-нибудь, к примеру:

ol-k_34
is
good
girl!

Сохраните и закройте этот файл.

Если у вас есть TotalCommander, то откройте файл, нажав кнопку F3.
Нажмите в меню Lister'a "Вид" -> "Шестнадцатеричный" (или клавишу 3)

Если у вас файловый менеджер - FAR, то откройте файл, нажав кнопку F3. Далее, нажмите F4.

Здесь и везде красное подчёркивание это пробел! (_ - это пробел)

Вы увидите следующую картину:
0000000000: 6F 6C 2D 6B 5F 33 34 0D | 0A 69 73 0D 0A 67 6F 6F ol-k_34..is..goo
0000000010: 64 0D 0A 67 69 72 6C 21 | 0D 0A _______________d..girl!..

Точками я обозначил "невидимые" символы (так делает программа hixdump в Linux'e, которая выводит тоже самое на экран)

Код 0Dh (13d) - CR Carriage Return (Перевод каретки) (см. раздел "Форматирование" --> ссылка)

Код 0Ah (10d) - LF Line Feed (Перевод строки)

Для вас важно, что:
1) В программе на Си код символа можно получить с помощью одинарных ковычек ''
Пример:
Код:
#include <stdio.h>

int main () {
    char c;

    c = 'o';
    printf("%x", c);

    printf("\n");
    return 0;
}
2) При переводе на другую строку не нужно писать символ перевода каретки (\r) и символ перевода строки (\n). Достаточно написать символ перевода строки (\n). Если нужно, то символ перевода каретки добавится в файл операционной системой. Если вы будите читать из файла, отыскивая символ перевода строки (\n), то последовательность 13d и 10d будет воспринята вашей функцией считывания, как один символ перевода строки(\n).
вот два эквивалентных способа:
Код:
#include <stdio.h>

int main () {
    char c;

    printf("Hello!");

    c = '\r';
    putchar(c);

    c = '\n';
    putchar(c);

    return 0;
}
Код:
#include <stdio.h>

int main () {
    char c;

    printf("Hello!");

    c = '\n';
    putchar(c);

    return 0;
}
3) Что касается EOF. Это код конца файла.

Код:
#include <stdio.h>

int main () {
    char c;

    c = EOF;
    printf("%d", c);

    printf("\n");
    return 0;
}
Когда символы в файле закончились - getchar вернёт его (EOF). В консоле EOF можно послать функции getchar() (которая томится в ожидании символа) c помощью Ctrl+Z, потом нажмите Enter (в windows).

Код:
#include <stdio.h>

int main () {
    char c;

    while ((c = getchar()) != EOF) {
        printf("Entered char: %4dd %4Xh", c, c);
        printf("\n");
    }

    printf("\n");
    printf("Last char: %d", c);
    printf("\n");
    return 0;
}
P.S. EOF объявлен с помощью define в файле stdio.h (этот файл мы подключаем с помощью директивы include). Обязательно найдите EOF в этом файле и напишите чему он равен.
8Observer8 вне форума Ответить с цитированием
Старый 11.02.2012, 11:33   #10
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Цитата:
Сообщение от ol-k_34 Посмотреть сообщение
Как понять считанный символ есть конец файла?
В нашей программе мы получаем коды символов с помощью getchar(). Эта функция возвращает код символа или EOF если символы закончились. Найдите описание функции в приложении Б (K&R), подраздел 1.4 "Функции ввода-вывода символов". (Не бойтесь заглядывать вперёд и проводить "разведку местности"). Есть ещё сайт по С/С++ cplusplus.com. Введите в поиске (на сайте cplusplus.com) getchar. Первая ссылка ваша. Переведите всё, что написано о getchar(). Не важно, что с первого раза не поймёте, просто сделайте это.

Цитата:
Сообщение от ol-k_34 Посмотреть сообщение
Т.е. мы вводим поток символов в строку и символ, который есть последний символ является концом потока символов, ну и строки тоже??? правильно?
Совершенно верно! Что бы проверить это проведите эксперимент. Запустите следующий код, вводите разные символы (пока не надоест). Когда устанете вводить нажмите Ctrl+Z, потом ENTER.

Я приводил следующий код, он и здесь к месту:
Код:
#include <stdio.h>

int main () {
    char c;

    while ((c = getchar()) != EOF) {
        printf("Entered char: %4dd %4Xh", c, c);
        printf("\n");
    }

    printf("\n");
    printf("Last char: %d", c);
    printf("\n");
    return 0;
}
P.S. Заметьте, что если вы введете один символ и нажмёте Enter, то программа выведет код символа и ещё один код. Понятно ли, что это за код - 10d? (буква d означает, что число представлено в десятичной системе счисления).

P.S.S. Не стесняйтесь задавать любые вопросы. Будем вместе разбираться
8Observer8 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Программированием С++ USB_ZVER Visual C++ 0 31.01.2012 21:16
Что случилось с программированием? Ozerich Свободное общение 42 19.03.2010 23:31
Проблемы с программированием на C whyer Помощь студентам 4 08.08.2009 22:17
Помогу с программированием Lokuson Фриланс 1 25.01.2009 11:34
Твердо решил занятся программированием vitis Помощь студентам 2 28.10.2008 21:51