Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> "Какая угодна длина строки" (с) 
:(
    Опции темы
Compositum
Дата 29.5.2011, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Язык программирования: C (не C++).
Книга: "Язык программирования C"; авторы: Брайан Керниган, Деннис Ритчи (второе издание).
Потихоньку, не торопясь, последовательно, на совесть выполняю все упражнения книги...
Сейчас выполняю упражнение 1.16 из раздела 1.9. (хотя прочитал намного дальше...).

Цитата(Текст упражнения)

Доработайте главный модуль программы определения самой длинной строки так, чтобы она выводила правильное значение для какой угодно длины строк входного потока, насколько это позволяет текст.

Мои размышления идут по такому пути: строка представляет собой массив объектов char, т.о., теоретически, самый простой вариант отведения необходимого объёма памяти - изначально создать массив char, имеющий максимально допустимую длину - тогда в неё поместится любая возможная строка. Это, конечно, неправильный подход, поскольку получается, что под какую-то единственную строку я могу запросить столько памяти, сколько на моей машине даже физически нет... Но, всё таки любопытно посмотреть, что из этого получится...

В разделе 1.6 "Массивы" обозначенной мною книги есть такая фраза:
Цитата(Керниган @  Ритчи)

Индексом может служить любое целочисленное выражение, в том числе целые переменные наподобие i или явные константы.

Из этого текста я делаю вывод, что в качестве размера массива я смогу задать значения таких типов как int, unsigned int, long int, unsigned long int.
Проверяю предположение:
Код

//Ритчи, урок 1.10, упр. 1.16
#include<stdio.h>

main(){
    
    unsigned int size1 = 100;
    long int size2 = 100;
    unsigned long int size3 = 100;
    
    char maxstring1[size1];
    char maxstring2[size2];
    char maxstring3[size3];    

    printf("Test...\n");
}

Результат:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/ritchi/1/1.9$ gcc 1.16.c -o 1.16.out
bush@mycomp:~/training/c/c89/ritchi/1/1.9$ ./1.16.out 
Test...
bush@mycomp:~/training/c/c89/ritchi/1/1.9$

Как видим - компиляция проходит успешно, а значит - перехожу к следующей стадии своей страшной затеи и сразу же беру быка за рога:
Код

//Ритчи, урок 1.10, упр. 1.16
#include<stdio.h>
#include<limits.h>

main(){
    char maxstring[ULONG_MAX];    
    maxstring[0] = '\0';
    printf("Test...\n");
}

Результат:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/ritchi/1/1.9$ gcc 1.16.c -o 1.16.out
1.16.c: In function ‘main’:
1.16.c:6:7: error: size of array ‘maxstring’ is too large
bush@mycomp:~/training/c/c89/ritchi/1/1.9$ 

Слишком большое... Хорошо, понижаю планку:
Код

//Ритчи, урок 1.10, упр. 1.16
#include<stdio.h>
#include<limits.h>

main(){
    char maxstring[LONG_MAX];        
    maxstring[0] = '\0';
    printf("Test...\n");
}

Результат:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/ritchi/1/1.9$ gcc 1.16.c -o 1.16.out
1.16.c: In function ‘main’:
1.16.c:5:1: error: total size of local objects too large
bush@mycomp:~/training/c/c89/ritchi/1/1.9$

Как видим, сообщение несколько изменилось, однако результат по прежнему отрицательный... Снова понижаю планку:
Код

//Ритчи, урок 1.10, упр. 1.16
#include<stdio.h>
#include<limits.h>

main(){
    char maxstring[INT_MAX];    
    maxstring[0] = '\0';
    printf("Test...\n");
}

Результат:
Цитата(Терминал)

bush@mycomp:~/training/c/c89/ritchi/1/1.9$ gcc 1.16.c -o 1.16.out
bush@mycomp:~/training/c/c89/ritchi/1/1.9$ ./1.16.out 
Segmentation fault
bush@mycomp:~/training/c/c89/ritchi/1/1.9$

Как видим - в этот раз компиляция прошла успешно, однако в процессе выполнения получаю ошибку. Из краткого сообщения, делаю предположение, что размер строки не может быть больше размера сегмента. Т.о. мои опасения на тему того, что теоретически я могу отдать под массив char памяти больше, чем у меня есть физически - не оправдались (и слава Богу smile)...

У меня 64-х разрядная операционная система (Ubuntu 11.04). Как можно программно (на C) получить размер сегмента (я так понимаю, что речь о сегменте памяти)? Правильно ли я понимаю, что под условие задачи (насчёт строки любой длины) я должен задавать размер массива char, равный размеру сегмента памяти (видимо разделение одной строки по нескольким сегментам не допустимо)?

Спасибо.


PM   Вверх
volatile
Дата 29.5.2011, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 16
Всего: 85



Цитата(Compositum @  29.5.2011,  21:44 Найти цитируемый пост)
Доработайте главный модуль программы определения самой длинной строки так, чтобы она выводила правильное значение для какой угодно длины строк входного потока, насколько это позволяет текст.

Скорей всего там вообще не надо отводить память. Если это входной поток, возможно нужно просто считать на лету.
Покажите о каком главном модуле, идет речь.
PM MAIL   Вверх
Compositum
Дата 30.5.2011, 07:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(volatile @ 29.5.2011,  23:26)
Цитата(Compositum @  29.5.2011,  21:44 Найти цитируемый пост)
Доработайте главный модуль программы определения самой длинной строки так, чтобы она выводила правильное значение для какой угодно длины строк входного потока, насколько это позволяет текст.

Скорей всего там вообще не надо отводить память. Если это входной поток, возможно нужно просто считать на лету.
Покажите о каком главном модуле, идет речь.

На данный момент мне быстрее показать скрин, чем набирать исходники (иначе на работу опоздаю) - выложил его здесь. Да, это входной поток, но в примере, прежде чем читать его, создаётся переменная longest (массив char, размером 1000). Я так понял, что вместо 1000 нужно подставить др. число, максимально допустимое для длины строки в потоке - вот я и пытался сделать это в первом сообщении топика...
PM   Вверх
bsa
Дата 30.5.2011, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Compositum, ты пытаешься найти решение несуществующей проблемы.
Допустим, у тебя есть строка какого-то размера (он заранее не известен), тебе гарантированно нужно сделать ее копию. Для этого достаточно воспользоваться циклом, realloc и методом выделения памяти, используемом в std::vector - размер выделенной памяти должен быть в 2 раза больше, чем было до этого. Таким образом, если по умолчанию ты будешь делать буфер размером 128 байт, то тебе понадобится всего 3 перевыделения, чтобы получить размер 1024 (128->256->512->1024).
PM   Вверх
Compositum
Дата 30.5.2011, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(bsa @ 30.5.2011,  13:48)
Compositum, ты пытаешься найти решение несуществующей проблемы.
Допустим, у тебя есть строка какого-то размера (он заранее не известен), тебе гарантированно нужно сделать ее копию. Для этого достаточно воспользоваться циклом, realloc и методом выделения памяти, используемом в std::vector - размер выделенной памяти должен быть в 2 раза больше, чем было до этого. Таким образом, если по умолчанию ты будешь делать буфер размером 128 байт, то тебе понадобится всего 3 перевыделения, чтобы получить размер 1024 (128->256->512->1024).

Я всего лишь последовательно выполняю упражнения. На той стадии, на которой находится обозначенная задача, авторами книги ещё не были обозначены никакие realloc и std::vector (повторюсь - это C, а не C++). Исходя из этого, я предполагаю, что авторы книги (они же и авторы языка C), подразумевают какой-то др. способ, доступный читателю на основе ранее изложенного материала...
PM   Вверх
bsa
Дата 30.5.2011, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Compositum, сделай так, чтобы если getline достигла лимита буфера, то она не ставила конец строки. Таким образом ты сможешь отследить этот момент и корректно вывести и строку, и ее размер. Хранить всю строку в памяти смысла нет никакого.
PM   Вверх
Compositum
Дата 30.5.2011, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(bsa @ 30.5.2011,  14:06)
Compositum, сделай так, чтобы если getline достигла лимита буфера, то она не ставила конец строки. Таким образом ты сможешь отследить этот момент и корректно вывести и строку, и ее размер. Хранить всю строку в памяти смысла нет никакого.

Но если строка выйдет за границы буфера (т.е. по сути - стека), то она начнёт писать данные поверх кода, стирая его... Или я ошибаюсь?
PM   Вверх
bsa
Дата 30.5.2011, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Compositum, читать надо кусочками. Прочитал кусок строки размером в MAXLEN, вывел, прочитал другой, тоже вывел, ... прочитал конец, вывел, вывел размер.
Это по сути тоже самое, что читать посимвольно и сразу выводить на экран.
PM   Вверх
Compositum
Дата 30.5.2011, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(bsa @ 30.5.2011,  14:53)
Compositum, читать надо кусочками. Прочитал кусок строки размером в MAXLEN, вывел, прочитал другой, тоже вывел, ... прочитал конец, вывел, вывел размер.
Это по сути тоже самое, что читать посимвольно и сразу выводить на экран.

Стоп. Хорошо, вот начну я выводить,  и вдруг окажется, что следующее слово будет ещё длиннее, а я уже "навыводил"... Тогда как? Я ведь смотрю в разрезе задачи, код которой показан мною на скрине, а в ней требуется из массива строк, поступающего на входе, выбрать самую большую...

Это сообщение отредактировал(а) Compositum - 31.5.2011, 06:32
PM   Вверх
bsa
Дата 31.5.2011, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(Compositum @  30.5.2011,  14:57 Найти цитируемый пост)
Я ведь смотрю в разрезе задачи, код которой показан мною на скрине, а в ней требуется из массива строк, поступающего на входе, выбрать самую большую...
Тебе что, нужно еще и вывести эту самую длинную строку? Или только вывести количество символов в ней?
PM   Вверх
Compositum
Дата 31.5.2011, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(bsa @ 31.5.2011,  12:18)
Тебе что, нужно еще и вывести эту самую длинную строку? Или только вывести количество символов в ней?

Я так понял, что показанный мною выше скрин ты не смотрел... smile
На нём в комментарии, перед main() озвучена решаемая задача: вывод самой длинной строки в потоке. На том же скрине, в самом низу след. страницы видно задание (упр. 1.16), о котором я собственно и пишу smile Тут следует учесть, что на данном этапе в книге указатели ещё не были изучены, т.о. задача должна решаться без них. И это C, а не C++. smile
Вот я и думаю, как зная только массивы, суметь обработать входной поток любого размера и вывести строку любой длины, насколько это позволяет текст (главный модуль - это код, показанный на стр. 42 моего скрина).
Я не понял фразы "насколько это позволяет текст"... Ведь текст - это массив символов. Массиву можно назначить далеко не каждый размер (это я показал в первом сообщении топика). Как правильно определить максимально возможный размер массива для того или иного типа данных?
PM   Вверх
bsa
Дата 31.5.2011, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(Compositum @  31.5.2011,  12:52 Найти цитируемый пост)
Я так понял, что показанный мною выше скрин ты не смотрел...
скрин я смотрел, но не читал все.
Перечитал все. Я не знаю решения задачи, без использования динамических массивов. Если бы речь шла о чтении файла, то можно было бы решить путем сохранения позиции максимальной строки в файле.
Возможно, в книге ошибка.

PM   Вверх
Compositum
Дата 31.5.2011, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Senior developer
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 430
Регистрация: 6.1.2008
Где: Санкт-Петербург

Репутация: нет
Всего: 1



Цитата(bsa @ 31.5.2011,  17:53)
Цитата(Compositum @  31.5.2011,  12:52 Найти цитируемый пост)
Я так понял, что показанный мною выше скрин ты не смотрел...
скрин я смотрел, но не читал все.
Перечитал все. Я не знаю решения задачи, без использования динамических массивов. Если бы речь шла о чтении файла, то можно было бы решить путем сохранения позиции максимальной строки в файле.
Возможно, в книге ошибка.

а я уж было подумал, что это я такой тупой, не могу простую задачку решить (сложную авторы вряд ли выложили бы на этой стадии)... smile Возможно кривой перевод (всё-таки издание ведь второе, вряд ли в оригинале бы такая ошибка была, хотя х.з.)...

Это сообщение отредактировал(а) Compositum - 31.5.2011, 18:53
PM   Вверх
xvr
Дата 1.6.2011, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(Compositum @  29.5.2011,  21:44 Найти цитируемый пост)
Из краткого сообщения, делаю предположение, что размер строки не может быть больше размера сегмента.

Неправильный вывод (пока оставим за бортом вопрос о существовании сегментов вообще). Твой массив расположен в стеке, вот именно он и переполнился. Сделай массив глобальным (объяви перед main)

PM MAIL   Вверх
Dov
Дата 1.6.2011, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

Репутация: 11
Всего: 88



В оригинале задача выглядит так: Revise the main routine of the longest-line program so it will correctly print the length of arbitrarily long input lines, and as much as possible of the text.

В моём (не совершенном) переводе это может звучать так:
Исправьте функцию main программы так, что бы она корректно выводила длину(т.е. количество символов) самой длинной строки и, как можно большее количество текста(ограниченное, как мы помним, значением MAXLINE).


Это сообщение отредактировал(а) Dov - 1.6.2011, 17:46


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0945 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.