Прекращена работа программы .exe в Code::Blocks

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
kernigan
Сообщения: 3
Зарегистрирован: 19 сен 2010, 17:57

Здравствуйте. Начал штудировать книгу Кергигана и Ричи по Си, дошел до массива символов, и столкнулся с не очень обычной для меня проблемой. Дело в том, что код, приведенный к качестве примера в книге, компилируется нормально, выдает черное окошко, можно даже ввести строчку. Но после нажатия enter Windows 7 выбрасывает служебное окно «Прекращена работа программы 5.exe, Windows может провести поиск способа устранения этой ошибки в интернете и бла-бла-бла."
Привожу код:

Код: Выделить всё

//считывает набор строк и выводит самую длинную из них
#include <stdio.h>
#define MAXLINE 1000

int getline(char line[], int);
void copy(char to[], char from[]);

//вывод самой длинной строки в потоке
main()
{
    int len;                //длина текущей строки
    int max;                //текущая максимальная длина
    char line[MAXLINE];     //текущая введенная строка
    char longest[MAXLINE];  //самая длинная строка из введенных

    max = 0;
    while ((len = getline(line, MAXLINE)) > 0)
        if (len > max)
            {
                max = len;
                copy(longest, line);
            }
    if (max > 0)          //была непустая строчка
        printf("%s", longest);
    return 0;
}

//считывает строку в s, возвращает ее длину
int getline(char s[], int lim)
{
    int c, i;

    for (i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)  //если строка от 1 до 1000 символов, не содержит 
        s[i] = c;                                                      //конца файла или новой строки, записать i-й символ 
                                                                          //в i-й элемент массива s[]
    if (c == '\n')          //как только ловим конец строки, записывает этот символ в последний i, полученный в цикле for
    {
        s[i] = c;
        ++i;                //окончательное значение количества символов в строке
    }
    s[i] = '\0';             //сообщаем о конце строки
    return i;
}
//копирует из одной строки в другую
void copy (char to[], char from[])
{
    int i;
    while ((to[i] = from[i]) != '\0')
            ++i;
}
Дело в компиляторе? Использую Code::blocks и MinGW.
IceFlame
Сообщения: 62
Зарегистрирован: 29 ноя 2009, 03:54

while ((len = getline(line, MAXLINE)) > 0)
Функция getline всегда будет выдавать длину хотя бы 1 символ, поэтому стоит изменить условие на ">1".
int i;
while ((to = from) != '\0')

Неплохо бы i инициализировать, соб-сно из-за случайного значения ii программа и крэшится.
kernigan
Сообщения: 3
Зарегистрирован: 19 сен 2010, 17:57

IceFlame писал(а): Неплохо бы i инициализировать, соб-сно из-за случайного значения ii программа и крэшится.
Потрясающе. Спасибо.
Еще у меня такой вопрос: почему EOF (ctrl+Z) срабатывает как конец файла только с новой строчки, а если набрать его на одной строчке с другими символами, он преобразуется в →?
IceFlame
Сообщения: 62
Зарегистрирован: 29 ноя 2009, 03:54

Странно, у меня в WinXP работает нормально на двух компиляторах - bcc и mingw.
kernigan
Сообщения: 3
Зарегистрирован: 19 сен 2010, 17:57

Модифицировал программу так, чтобы она переворачивала все строки с помощью функции reverse. Все вроде работает, но меня смущает мусор, выбрасываемый в конце:
Изображение
Что бы это могло быть?

Код: Выделить всё

#include <stdio.h>
#define MAXLINE 1000

int getline (char s[], int);
void reverse(char to[], char from[], int);

main()
{
    int len, j, i;
    char rev[MAXLINE], line[MAXLINE], ex[MAXLINE];

    j = 0;
    while ((len = getline(line, MAXLINE)) > 0)
        {
            reverse(rev, line, len);
            for (i = 0; i < len; ++i)
            {
                ex[j] = rev[i];
                ++j;
            }
        }
    printf("%s", ex);
}

int getline (char s[], int lim)
{
    int i, c;
    for (i = 0; i < lim - 1 && (c = getchar()) != '\n' && c != EOF; ++i)
        s[i] = c;
    if (c == '\n')
    {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;
}

void reverse (char to[], char from[], int len)
{
    int i;
    for (i = 0; i < len; ++i)
        to[i] = from[len - 2 - i];
    to[len - 1] = '\n';
    to[len] = '\0';
}
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

В функции reverse i бежит от 0 до len-1, таким образом при i=len-1 выражение len - 2 - i (которое стоит в качестве индекса у массива символов from) примет значение len - 2 - (len-1) = -1.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить