Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
3 / 3 / 2
Регистрация: 15.05.2015
Сообщений: 93
1

Керниган/Ритчи упражнение 1.22

10.08.2017, 22:09. Показов 2370. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
"Упражнение 1.22. Напишите программу, печатающую символы входного потока так, чтобы строки текста не
выходили правее n-й позиции. Это значит, что каждая строка, длина которой превышает n, должна печататься
с переносом на следующие строки. Место переноса следует "искать" после последнего символа, отличного от
символа-разделителя, расположенного левее n-й позиции. Позаботьтесь о том, чтобы ваша программа вела
себя разумно в случае очень длинных строк, а также когда до n-й позиции не встречается ни одного символа
пробела или табуляции."

При выполнении программы ошибка такого рода на скриншоте
Миниатюры
Керниган/Ритчи упражнение 1.22  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.08.2017, 22:09
Ответы с готовыми решениями:

Керниган/Ритчи упражнение 1.20
"Упражнение 1.20. Напишите программу detab, заменяющую символы табуляции во вводимом тексте нужным...

Керниган Ритчи Упражнение 2.2
Добрый день. Помогите начинающему разобраться пожалуйста. Само задание я решил, но...

Керниган, Ритчи, указатели и упражнение 5.3
Добрый день! "Напишите свою версию функции strcat, ... с применением указателей." void...

Выделить преобразование температур в отдельную функцию. (Керниган и Ритчи: Упражнение 1.15)
Немного сцитирую: Итак, мы имеем функцию power и главную функцию main, пользующуюся ее услугами,...

13
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
10.08.2017, 22:47 2
AlexeyChun, что за getline ? как это вообще скомпилировалось? в stdio нет такой функции, есть gets(). более того вы пытаетесь зачитать строку в int, а потом исользуете putchar(). какая то каша. Строки считываются в буффер.
0
3 / 3 / 2
Регистрация: 15.05.2015
Сообщений: 93
10.08.2017, 23:22  [ТС] 3
Цитата Сообщение от _SayHello Посмотреть сообщение
что за getline ? как это вообще скомпилировалось? в stdio нет такой функции, есть gets(). более того вы пытаетесь зачитать строку в int, а потом исользуете putchar(). какая то каша. Строки считываются в буффер.

точно) getchar() же

поправил код, но в первой строке почему-то после любого i-го символа бросает на новую строку.
Миниатюры
Керниган/Ритчи упражнение 1.22  
0
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
10.08.2017, 23:59 4
AlexeyChun, у вас проверка условия какое то странное, в одном вы сравниваете i в том же переменную с.
0
3 / 3 / 2
Регистрация: 15.05.2015
Сообщений: 93
11.08.2017, 00:22  [ТС] 5
Цитата Сообщение от _SayHello Посмотреть сообщение
у вас проверка условия какое то странное, в одном вы сравниваете i в том же переменную с.
когда i > N по условиям задачи нужно оставить пробелы/табуляцию на той же строке, вот поэтому решил выделить в else проверку на пробел/табуляцию.

Вообщем в i сохраняется значение числа символов предыдущей строки до ввода новой для деления. Как понимаю нужн окак-то очистить буфер.
0
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
11.08.2017, 00:33 6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
while(c=getchar() != EOF)
{
       if(i < N) 
       {
             putchar(c);
             i++;
        }
       else
        {
             if (c == ' ' || c == '\t') putchar(c);
             putchar('\n');
             i=0;
         }
}
если все правильно понял
0
3 / 3 / 2
Регистрация: 15.05.2015
Сообщений: 93
11.08.2017, 00:59  [ТС] 7
1. у операций сравнения приоритет выше присваивания.
2. в конце строки может быть несколько символов-пробелов/табуляций.
0
3 / 3 / 2
Регистрация: 15.05.2015
Сообщений: 93
11.08.2017, 01:06  [ТС] 8
Вот он разбивает длинные строки...первая строка явно короткая, потому что в i хранится значение длины предыдущей строки. Вопрос как его сбрасывать, это значение.
Миниатюры
Керниган/Ритчи упражнение 1.22  
0
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
11.08.2017, 01:10 9
AlexeyChun, 1. неудобно писать в блокноте) 2. Попробуй так, нет возможности скомпилировать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
while((c=getchar()) != EOF)
{
       if(i < N) 
       {
             putchar(c);
             i++;
        }
       else
        {
             if (c == ' ' || c == '\t') 
                 putchar(c);
             else
             {
                 putchar('\n');
                 i=0;
              }
         }
}
Добавлено через 4 минуты
AlexeyChun, вы операцию ветвления видимо неправильно поняли. в структурe if..ifelse..else может выполняться только одна ветка, тогда как у вас, может одновременно выполняться две так как может выполняться первый if так как i < N, и одновременно выполняться другое условие else if, так как c может быть и пробелом и табуляцией.
0
3 / 3 / 2
Регистрация: 15.05.2015
Сообщений: 93
11.08.2017, 02:01  [ТС] 10
Цитата Сообщение от _SayHello Посмотреть сообщение
вы операцию ветвления видимо неправильно поняли. в структурe if..ifelse..else может выполняться только одна ветка, тогда как у вас, может одновременно выполняться две так как может выполняться первый if так как i < N, и одновременно выполняться другое условие else if, так как c может быть и пробелом и табуляцией.
По-моему это не так, да и компилятор подтверждает) если бы было так, то бы символ удваивался по putchar(c) в обоих ветвлениях, а этого не происходит
0
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
11.08.2017, 11:23 11
AlexeyChun, все я наконец то понял, про пробелы и табуляцию в задаче. Я сначала подумал, что пробелы и табуляцию надо проверять и до i < N и поэтому и сказал, что elseif не будет выполняться пока выполняется if.
0
737 / 542 / 416
Регистрация: 17.09.2015
Сообщений: 1,601
11.08.2017, 11:43 12
у вас обоих нет решения вот этого пункта
Цитата Сообщение от AlexeyChun Посмотреть сообщение
Место переноса следует "искать" после последнего символа, отличного от
символа-разделителя, расположенного левее n-й позиции.
0
3 / 3 / 2
Регистрация: 15.05.2015
Сообщений: 93
11.08.2017, 12:13  [ТС] 13
Цитата Сообщение от LFC Посмотреть сообщение
у вас обоих нет решения вот этого пункта
Сообщение от AlexeyChun
Место переноса следует "искать" после последнего символа, отличного от
символа-разделителя, расположенного левее n-й позиции.
С трудом понимаю что это.
Объясните что это - "трудности перевода" в книге или вполне себе задача.
0
737 / 542 / 416
Регистрация: 17.09.2015
Сообщений: 1,601
11.08.2017, 13:12 14
имеется ввиду чтобы слова переносились целиком а не разрывались если на N-ю позицию приходится середина слова, т.е. чтобы местом переноса был пробельный символ.
Допустим
C
1
#define N 10
Ввод:
Every breath you take
Вывод должен быть:
Every
breath you
take
А у вас получится:
Every brea
th you tak
e

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <stdio.h>
#include <stdlib.h>
#define N 20
#define TAB 4
//если табуляция больше 4-х пробелов введите нужное значение
int isSpace(char );
void myPrint(char *, int );
 
int main()
{
    char str[BUFSIZ];
    int i = 0, j, k;
    puts("Enter text:");
    while((str[i] = getchar()) != '\n'){
        if(str[i] == '\t'){
            for(int m = 0; m < TAB; m++, i++)//заменяем \t на пробелы,т.к. таб считается одним символом
                str[i] = ' ';  //а при печати занимает место как 4 символа и строка может вылезти сильно вправо
            i--;
            if(i > N)
                i = N;
        }
        if(i == N){
            if(isSpace(str[i])){//если N-позиция пробельный символ,
                myPrint(str, i); //то печатаем строку и делаем перенос
                str[0] = str[i]; //символ с N-позиции переносим в начало следущей строки
                i = 1; //и её начнем заполнять со второго элемента
            }
            else{ //если N-позиция внутри слова
                k = i - 1;
                while(k && !isSpace(str[k]))//то ищем ближайший пробельный символ слева
                    k--;
                if(!k){//если во всей строке не нашлось пробельных символов
                    myPrint(str, i);//печатаем ее "как есть"
                    str[0] = str[i];
                    i = 1;
                }
                else{                    //если пробельный символ есть,
                    myPrint(str, k + 1);//то печатаем строку до него включительно
                    for(j = 0, k++; k <= i; )//а оставшийся конец строки
                        str[j++] = str[k++]; //копируем в начало следующей
                    i = j;
                }
            }
        }
        else
            i++;
    }
    if(i) //допечатываем остаток буфера < N
        myPrint(str, i);
    return 0;
}
int isSpace(char c)
{
    if(c == ' ' || c == '\t' || c == '\n')
        return 1;
    return 0;
}
void myPrint(char *s, int size)
{
    for(int i = 0; i < size; i++)
        putchar(*(s + i));
    putchar('\n');
}
1
11.08.2017, 13:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.08.2017, 13:12
Помогаю со студенческими работами здесь

Ритчи и Керниган
В этом учебники в некоторых примерах прототип функции объявляется внутри другой функции. Доля того,...

Компилятор С(Керниган ,Ритчи)
Здравствуйте! Открыл книгу Брайана Кернигана и Денниса Ритчи. Первое задание MAIN()...

Указатели, Керниган и Ритчи 5.4
Здравствуйте, нужна помощь начинающему. Читаю Керниган и Ритчи и не могу понять следующую вещь:...

Керниган/ритчи задачи 1.18
Упражнение 1.18. Напишите программу, которая будет в каждой вводимой строке заменять стоящие подряд...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru