2014 dxdy logo

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

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




 
 Списки. Язык Си.
Сообщение16.02.2014, 14:25 
Здравствуйте. Вообщем есть задача: дана последовательность символов оканчивающаяся точкой удалить все символы, у которых равные соседи (первый и последний считать соседями). Последовательность представлена в виде двунаправленного циклического списка.
Программа не хочет удалять эти символы.

Код:
#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 
Можно do { /* ... */ } while (ch != head) сделать. Но у вас другая проблема — если был список ...xababy..., то он должен превратиться в ...xaby..., а не в ...xaaby....

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


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

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


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



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

 
 
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 18:56 
Значит, вы компилируете исходный код, сильно отличный от приведенного в исходном сообщении. Кстати, в Си нету new.

 
 
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 19:11 
Joker_vD в сообщении #827295 писал(а):
Значит, вы компилируете исходный код, сильно отличный от приведенного в исходном сообщении. Кстати, в Си нету new.


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

 
 
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 19:20 
Аватара пользователя
Joker_vD в сообщении #827295 писал(а):
Кстати, в Си нету new.
Это вам намекают на то, что new — оператор C++, но не Си.

 
 
 
 Re: Списки. Язык Си.
Сообщение16.02.2014, 19:20 
Аватара пользователя
Retard в сообщении #827302 писал(а):
Разве нет? Мы (в институте) изучаем Си и начали использовать new.
Это либо кто-то плохо изучает, либо кто-то плохо преподает. C и С++ это разные языки.

 
 
 
 Re: Списки. Язык Си.
Сообщение18.02.2014, 00:47 
Аватара пользователя
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 
NT2000 в сообщении #827958 писал(а):
new и delete - поправьте.

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

 
 
 
 Re: Списки. Язык Си.
Сообщение19.02.2014, 21:16 
Попробовал так, но всё равно не работает:

Код:
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 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group