2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Списки. Язык Си.
Сообщение16.02.2014, 14:25 


23/10/13
46
Здравствуйте. Вообщем есть задача: дана последовательность символов оканчивающаяся точкой удалить все символы, у которых равные соседи (первый и последний считать соседями). Последовательность представлена в виде двунаправленного циклического списка.
Программа не хочет удалять эти символы.

Код:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

#define INPUT_FILENAME "input.txt"
#define OUTPUT_FILENAME "output.txt"

struct characters {
    char data;
    characters* next;
    characters* prev;
};

characters* readList (FILE* file);
void deleteChars(characters* ch);
void writeList(FILE* file, characters* ch);

int main()
{
    FILE *read, *write;
    characters* qList;

    if ((read = fopen(INPUT_FILENAME, "r")) == NULL) {
        printf("\nError. Can't open file %s.", INPUT_FILENAME);
    }
    qList = readList(read);
    fclose(read);

    if ((write = fopen(OUTPUT_FILENAME, "w")) == NULL) {
        printf("\nError. Can't open file %s.",OUTPUT_FILENAME);
    }
    deleteChars(qList);
    writeList(write, qList);
    fclose(write);
    _getch();
    return 0;
}

characters* readList (FILE* file)
{
    characters *ch, *head;
    char c;

    head = new characters;
    ch = head;

    while ((c = fgetc(file)) != '.')
    {
        ch->next = new characters;
        ch->next->prev = ch;
        ch->data = c;
        ch = ch->next;
    }

    ch->next=head;
    head->prev = ch;

    return head;
}

void deleteChars(characters* ch)
{
     characters* head = ch;
     characters* ptmp;
     while (ch != head)
      {
           if (ch->prev->data == ch->next->data)
                   {
                ch->next->prev = ch->prev;
                ch->prev->next = ch->next;
                ptmp = ch;
                delete ptmp;
           }
            ch = ch->next;
      }
      ch = head;
}


void writeList(FILE* file, characters* ch)
{
    characters* head = ch;

    while (ch->next != head)
    {
        fprintf(file, "%c", ch->data);
        ch = ch->next;
    }
}


Думаю, ошибка вот тут, но что присваивать characters* head?:

Код:
void deleteChars(characters* ch)
{
     characters* head = ch;
     characters* ptmp;
     while (ch != head)

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 14:37 
Заслуженный участник


09/09/10
3729
Можно do { /* ... */ } while (ch != head) сделать. Но у вас другая проблема — если был список ...xababy..., то он должен превратиться в ...xaby..., а не в ...xaaby....

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 15:14 


23/10/13
46
Joker_vD в сообщении #827165 писал(а):
Можно do { /* ... */ } while (ch != head) сделать. Но у вас другая проблема — если был список ...xababy..., то он должен превратиться в ...xaby..., а не в ...xaaby....


Если сделать do...while , то ошибку выдаёт якобы переменная read не инициализирована.

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 17:37 


23/10/13
46
Retard в сообщении #827186 писал(а):
Joker_vD в сообщении #827165 писал(а):
Можно do { /* ... */ } while (ch != head) сделать. Но у вас другая проблема — если был список ...xababy..., то он должен превратиться в ...xaby..., а не в ...xaaby....


Если сделать do...while , то ошибку выдаёт якобы переменная read не инициализирована.



Хотя теперь так не пишет, просто прекращается работа программы

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 18:56 
Заслуженный участник


09/09/10
3729
Значит, вы компилируете исходный код, сильно отличный от приведенного в исходном сообщении. Кстати, в Си нету new.

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 19:11 


23/10/13
46
Joker_vD в сообщении #827295 писал(а):
Значит, вы компилируете исходный код, сильно отличный от приведенного в исходном сообщении. Кстати, в Си нету new.


Таки нет, я использую тот же код, только меняю while do на do while и всё.
Разве нет? Мы (в институте) изучаем Си и начали использовать new.

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 19:20 
Аватара пользователя


11/06/12
10390
стихия.вздох.мюсли
Joker_vD в сообщении #827295 писал(а):
Кстати, в Си нету new.
Это вам намекают на то, что new — оператор C++, но не Си.

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 19:20 
Заслуженный участник
Аватара пользователя


06/10/08
6422
Retard в сообщении #827302 писал(а):
Разве нет? Мы (в институте) изучаем Си и начали использовать new.
Это либо кто-то плохо изучает, либо кто-то плохо преподает. C и С++ это разные языки.

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение18.02.2014, 00:47 
Аватара пользователя


28/01/12
467
Retard в сообщении #827156 писал(а):
Код:
void deleteChars(characters* ch)
{
     characters* head = ch;
     characters* ptmp;
     while (ch != head)
      {
           if (ch->prev->data == ch->next->data)
           {
                ch->next->prev = ch->prev;
                ch->prev->next = ch->next;
                ptmp = ch; //??
                delete ptmp; //??
           }
           ch = ch->next;
      }
      ch = head;
}

И оператора delete тоже в С нет.
new и delete - поправьте.
Еще, обратите внимание на 2 строчки отмеченные //??
Устанавливаете указатель ptmp и тут же его удаляете - ?!
Не понятно, чего хотели достичь?

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение18.02.2014, 09:40 
Заслуженный участник


02/08/11
7013
NT2000 в сообщении #827958 писал(а):
new и delete - поправьте.

Да пусть остаются. Программа-то не из-за них не работает.

 Профиль  
                  
 
 Re: Списки. Язык Си.
Сообщение19.02.2014, 21:16 


23/10/13
46
Попробовал так, но всё равно не работает:

Код:
void deleteChars(characters* ch)
{
        while (ch->data != '.')
        {
                if ( (ch->prev)->data == (ch->next)->data ) )
                        deleteItem(ch);
                characters* toDel = ch;
                ch = ch->next;
                delete toDel;
        }
}

void deleteItem(characters* ch)
{
        (ch -> prev) -> next = ch -> next;
        (ch -> next) -> prev = ch -> prev;
}


Отладчик показывает, что цикл почему-то продолжается после того, как нашли точку, причём точку он заменяет на "=", потом ещё 2 раза проходит и крашится.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group