Завершил работу над основным проектом по программированию, который нужно было сделать к концу первого этапа курсов в НИИТе. Цель проекта - создать программу-компрессор, сжимающую файлы по методу Хаффмана.
Разложил задачу на отдельные самостоятельные блоки, каждый из которых выполняет определённую часть работы, принимая и возвращая необходимые данные через функцию-интерфейс. Реализовал алгоритм сжатия. Проект собирается при помощи GNU make (кстати, отличная вещь!). Кроме того, выполнил необязательную часть задания - реализовал в программе возможность распаковки (декомпрессии) сжатых файлов и написал краткую документацию по проекту.
Позавчера сломал себе всю голову, пытаясь разработать алгоритм сортировки бинарного дерева. Вчера и сегодня целый день работал над проектом, вылавливал ошибки в коде (часто отладка занимает времени не меньше, чем написание кода).
Завтра экзамен по программированию в НИИТе. Нужно немного отдохнуть и подготовиться.
Показаны сообщения с ярлыком программирование. Показать все сообщения
Показаны сообщения с ярлыком программирование. Показать все сообщения
10 марта 2011 г.
29 мая 2010 г.
Изучаю C++. Проблемы с функцией fgets(). Выкидываем символ новой строки из строковой переменной.
Я люблю хорошую музыку. Вы тоже? Отлично. А ещё я люблю переделывать простые и скучные программы из учебников по программированию, добавляя в них дополнительную функциональность и улучшая их. В одной из таких программ (Герберт Шильдт, "C++. Руководство для начинающих, 2-е изд.", стр.182-183) предлагалось написать простой телефонный справочник, используя массив строк. Стоп, телефонный справочник?.. гм... звучит не очень интересно. Я попробовал создать небольшую и простую музыкальную базу данных. Конечно, то, что получилось, было мало похоже на Musicbrainz или Discogs... Ну конечно, ведь это - просто улучшенная версия телефонного справочника из учебника по C++.
Итак, что мы имеем изначально? Программа, приведённая в книге, очень проста. Создаётся массив строк numbers[10][80], этот массив сразу заполняется данными: имя, телефон, имя, телефон ... и т. д. Вы вводите имя, программа последовательно сравнивает введённую вами строку с элементами строкового массива. Если есть совпадение, программа отображает телефонный номер. Конец программы.
Теперь пора превратить этот телефонный справочник в музыкальную БД. Во-первых, я поменял название массива и сделал его "безразмерным", вот так: bands[][200]. Как видите, компилятор сам подсчитывает количество строк массива. Кроме того, я увеличил количество столбцов массива (т. е. максимальную длину записи) до 200, чтобы можно было перечислить несколько альбомов для каждого музыканта:
Здесь я добавил в конце массива две пустые строки, содержащие нулевой символ "\0" (компилятор самостоятельно добавляет этот символ в конце каждой строковой переменной). Это пригодится для огранизации цикла последовательного просмотра элементов строкового массива.
Поместил считывание строки, поиск совпадений, и вывод результата в бесконечный цикл, из которого два выхода (а как же иначе?..) - или клавиша <q>, или... <Ctrl>+<c>.
Теперь проблема с cin >> str; - нам не удастся ввести название группы, состоящее из нескольких слов, разделённых пробелами - знак пробела будет воспринят как конец ввода и в переменную str попадёт только первое слово из названия группы. Чтобы исправить это, потребуется использовать... ну, скажем, fgets(str, 100, stdin) для считывания строки. Однако именно эта функция и явилась причиной очень занятного бага, из-за которого программа не могла корректно работать. Дело в том, что функция fgets() прежде, чем завершить свою работу после нажатия <Enter>, считывает в строковую переменную str символ новой строки "\n"! Из-за этой "особенности" функция strcmp(str, bands[i]) работала некорректно - как я не бился, она "в упор" не видела очевидные совпадения введённой строки с элементом строкового массива... И вот теперь я знаю, в чём дело. Но как это исправить? В Интернете нашлось несколько различных howto на тему "как выкинуть ненужный символ новой строки из переменной". Однако все эти способы показались мне чресчур сложными для подобной задачи. После размышлений, я написал следующее:
После этого программа стала работать корректно.
В процессе изучения языка C++ я часто сталкиваюсь с различными проблемами, которые пытаюсь решить. Иногда это бывает очень просто, а иногда приходится потратить немало времени. В большинстве случаев, больше всего времени уходит на то, чтобы понять, где же я ошибся.
А вообще, на поиск и исправление ошибок может уйти время даже большее, чем на написание самой программы.
Итак, что мы имеем изначально? Программа, приведённая в книге, очень проста. Создаётся массив строк numbers[10][80], этот массив сразу заполняется данными: имя, телефон, имя, телефон ... и т. д. Вы вводите имя, программа последовательно сравнивает введённую вами строку с элементами строкового массива. Если есть совпадение, программа отображает телефонный номер. Конец программы.
cin >> str; // Считываем строку в символьную (char) переменную str[80]
for(i = 0; i < 10; i += 2)
if(!strcmp(str, numbers[i])) { // Проверяем на совпадение с элементом массива
cout << "Телефонный номер: " // и выводим на экран
<< numbers[i+1] << "\n";// телефонный номер break; }Теперь пора превратить этот телефонный справочник в музыкальную БД. Во-первых, я поменял название массива и сделал его "безразмерным", вот так: bands[][200]. Как видите, компилятор сам подсчитывает количество строк массива. Кроме того, я увеличил количество столбцов массива (т. е. максимальную длину записи) до 200, чтобы можно было перечислить несколько альбомов для каждого музыканта:
char bands[][200] = {
"группа1", "альбом1, альбом2 ...",
"группа2", "альбом1, альбом2, альбом3 ...",
// ...
"группаN", "альбом1, альбом2 ...",
"", ""
};
Здесь я добавил в конце массива две пустые строки, содержащие нулевой символ "\0" (компилятор самостоятельно добавляет этот символ в конце каждой строковой переменной). Это пригодится для огранизации цикла последовательного просмотра элементов строкового массива.
Поместил считывание строки, поиск совпадений, и вывод результата в бесконечный цикл, из которого два выхода (а как же иначе?..) - или клавиша <q>, или... <Ctrl>+<c>.
Теперь проблема с cin >> str; - нам не удастся ввести название группы, состоящее из нескольких слов, разделённых пробелами - знак пробела будет воспринят как конец ввода и в переменную str попадёт только первое слово из названия группы. Чтобы исправить это, потребуется использовать... ну, скажем, fgets(str, 100, stdin) для считывания строки. Однако именно эта функция и явилась причиной очень занятного бага, из-за которого программа не могла корректно работать. Дело в том, что функция fgets() прежде, чем завершить свою работу после нажатия <Enter>, считывает в строковую переменную str символ новой строки "\n"! Из-за этой "особенности" функция strcmp(str, bands[i]) работала некорректно - как я не бился, она "в упор" не видела очевидные совпадения введённой строки с элементом строкового массива... И вот теперь я знаю, в чём дело. Но как это исправить? В Интернете нашлось несколько различных howto на тему "как выкинуть ненужный символ новой строки из переменной". Однако все эти способы показались мне чресчур сложными для подобной задачи. После размышлений, я написал следующее:
// с функцией fgets проблема...
fgets(str, 100, stdin);
// ...она передаёт в символьную переменную str, кроме "обычных" символов,
// символ новой строки (\n). Из-за этого операции со str выполняются некорректно.
// Поэтому, с помощью простого цикла, мы находим символ конца строки
// и заменяем его на нулевой символ.
for(i = 0; i < strlen(str); i++) if(str[i] == '\n') str[i] = 0; После этого программа стала работать корректно.
В процессе изучения языка C++ я часто сталкиваюсь с различными проблемами, которые пытаюсь решить. Иногда это бывает очень просто, а иногда приходится потратить немало времени. В большинстве случаев, больше всего времени уходит на то, чтобы понять, где же я ошибся.
А вообще, на поиск и исправление ошибок может уйти время даже большее, чем на написание самой программы.
17 декабря 2009 г.
Интервью с Дональдом Кнутом (перевод с английского)
Вот интервью, которое я прочитал сегодня. Хотя, возможно, это не самая замечательная его часть (там есть ещё много интересного), тем не менее, вот цитата:
"Успех программ с открытыми текстами – это, вероятно, единственное явление в компьютерной области, которому я в последние несколько десятилетий не удивляюсь. Но это движение еще не реализовало весь свой потенциал; я полагаю, что программы с открытыми текстами будут становиться полностью доминирующими по мере того, как экономика будет все больше полагаться не на продукты, а на услуги, и будет появляться все больше добровольцев, желающих совершенствовать программы."
- Дональд Кнут (Donald Knuth)
Полный текст интервью здесь: http://citcity.ru/18573/
Автор перевода: Сергей Кузнецов
"Успех программ с открытыми текстами – это, вероятно, единственное явление в компьютерной области, которому я в последние несколько десятилетий не удивляюсь. Но это движение еще не реализовало весь свой потенциал; я полагаю, что программы с открытыми текстами будут становиться полностью доминирующими по мере того, как экономика будет все больше полагаться не на продукты, а на услуги, и будет появляться все больше добровольцев, желающих совершенствовать программы."
- Дональд Кнут (Donald Knuth)
Полный текст интервью здесь: http://citcity.ru/18573/
Автор перевода: Сергей Кузнецов
25 октября 2009 г.
История одного программиста
На занятия программированием меня подвигло желание сделать с помощью компьютера что-то своё, что будет работать и выполнять какую-то задачу. В школе я начал изучать язык программирования Паскаль (Pascal). "По-умолчанию" тогда на уроках информатики изучали Бейсик (Basic), но Паскаль для меня был более интересен. Сейчас это мне кажется смешным, но в то время я хотел в будущем серьёзно заняться созданием компьютерных игр. Тогда из всего времени, что я проводил за компьютером, на компьютерные игры у меня уходило от 80 до 100 процентов времени. Таким образом получалось, что большую часть свободного времени я играл в компьютерные игры. Конечно, это отрицательно сказывалось на моей учёбе в школе, и вспоминая то время, я очень сожалею об этом.
Изучив основы языка Паскаль, я приступил к изучению среды разработки Delphi - и к моменту окончания школы у меня уже были некоторые знания "о компьютерах вообще" и программировании. В 2006 году я поступил в ВУЗ и устроился там же работать. На работе у меня впервые появился интернет. Хотя программированием как таковым в это время я мало занимался, мне было интересно разбираться в тонкостях настройки ОС Windows, которая стояла и на домашнем ПК, и на работе. Разочаровавшись в намерении стать разработчиком компьютерных игр, интерес к написанию собственных программ угас. Серьёзный интерес к программированию вновь появился в лишь 2009 году. Заинтересовавшись свободным ПО, начал изучать свободную реализацию языка Паскаль - Free Pascal - и перешёл на Delphi-подобную свободную среду разработки Lazarus, в которой работаю и по сей день.
Как вы можете видеть, в разное время я руководствовался разными целями и разными интересами, изучая программирование. Но на этом моя история, как программиста, не заканчивается - напротив, мне кажется, что она только начинается.
Изучив основы языка Паскаль, я приступил к изучению среды разработки Delphi - и к моменту окончания школы у меня уже были некоторые знания "о компьютерах вообще" и программировании. В 2006 году я поступил в ВУЗ и устроился там же работать. На работе у меня впервые появился интернет. Хотя программированием как таковым в это время я мало занимался, мне было интересно разбираться в тонкостях настройки ОС Windows, которая стояла и на домашнем ПК, и на работе. Разочаровавшись в намерении стать разработчиком компьютерных игр, интерес к написанию собственных программ угас. Серьёзный интерес к программированию вновь появился в лишь 2009 году. Заинтересовавшись свободным ПО, начал изучать свободную реализацию языка Паскаль - Free Pascal - и перешёл на Delphi-подобную свободную среду разработки Lazarus, в которой работаю и по сей день.
Как вы можете видеть, в разное время я руководствовался разными целями и разными интересами, изучая программирование. Но на этом моя история, как программиста, не заканчивается - напротив, мне кажется, что она только начинается.
Подписаться на:
Сообщения (Atom)