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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Печать данных двулинейного направленного списка, Проблема с выводом списка 
:(
    Опции темы
mes
Дата 4.6.2008, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(SubZero @  4.6.2008,  15:19 Найти цитируемый пост)
Да, немного) Дело в цикле while:
Код

while (ptrCurrent)
            {
               ShowAuto(ptrCurrent->car);
               ptrCurrent=ptrCurrent->next;
    }
В последней итерации цикла ptrCurrent становится равным NULL


если ptrCurrent == NULL, то тело while не выполняется..



Цитата(SubZero @  4.6.2008,  15:19 Найти цитируемый пост)
Что касается выделения памяти, то, само собой, я это делаю. Посмотри функции InputAuto() и LoadAutos() 

посмотрел функцию LoadAutos - не нашел где выделяется  память для указателя p  smile 

P.S. 
Цитата(SubZero @  4.6.2008,  15:19 Найти цитируемый пост)
P.S. Как правильно цитировать пост несколько раз по частям, что-то не пойму как это сделать.. 

выделяй нужную часть и жми "быстрая цитата" ))


--------------------
PM MAIL WWW   Вверх
SubZero
Дата 4.6.2008, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.6.2008

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



Цитата(mes @  4.6.2008,  16:00 Найти цитируемый пост)
посмотрел функцию LoadAutos - не нашел где выделяется  память для указателя p   


Точно, исправил при объявлении: 


Код

int main()
{
       avto *p = new avto;


Надеюсь так нормально? Программа вроде работает smile

Теперь парадокс, связанный с использованием cout(). Если вместо

Код

    cout<<car.mark<<"\n";
    cout<<car.colour<<"\n";
    cout<<car.number<<"\n";


пишу

Код

    printf("\n%s", car.mark);
    printf("\n%s", car.colour);
    printf("\n%s", car.number);


то программа вылетает с кучей ошибок. Тоже не могу понять в чем проблема, вроде бы все пишу правильно..  smile 
PM MAIL   Вверх
mes
Дата 4.6.2008, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(SubZero @  4.6.2008,  16:12 Найти цитируемый пост)
Надеюсь так нормально? Программа вроде работает 

если тебе надо на чистом С, то там операции new нет 
если все же на "облегченном" C++, то тогда замени и malloc

Цитата(SubZero @  4.6.2008,  16:12 Найти цитируемый пост)
то программа вылетает с кучей ошибок. Тоже не могу понять в чем проблема, вроде бы все пишу правильно..    

не компилируется, или вылетает при исполнении ?
если не компилится,  то коды ошибок в студию..

Это сообщение отредактировал(а) mes - 4.6.2008, 17:02


--------------------
PM MAIL WWW   Вверх
SubZero
Дата 5.6.2008, 09:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.6.2008

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



Цитата(mes @  4.6.2008,  17:02 Найти цитируемый пост)
если тебе надо на чистом С, то там операции new нет 
если все же на "облегченном" C++, то тогда замени и malloc

верно, забыл исправить) Заменил

Код

avto *p = new avto


на

Код

avto *p = (avto *) malloc ( sizeof (avto))


Программа работает правильно. Теперь осталось избавиться только от cout() и программа будет уже на чистом С  smile


Цитата(mes @  4.6.2008,  17:02 Найти цитируемый пост)
не компилируется, или вылетает при исполнении ?
если не компилится,  то коды ошибок в студию..


Программа работает, но неправильно. Вместо

Код

fer
red
768


она печатает на экране кучу ерунды и выводит в итоге в файл много мусора

Код

fer red 768
ш  яюяюяюяю
Ђь†t ДДК r#QRё@ шuѓкsс&Ж 
лылшГPё@ OU‹м‹F
]© 
иНюrkН±Уа‹И+ГчШѓйЋБ&Ж ЋБ&Ж З
щ—єўЉйэ1и«r&Ђ=  0<$tиD

  
***


Вместо этого в файл должно выводиться

Код

fer red 768
***


Вот такая вот ерунда..   smile 

Это сообщение отредактировал(а) SubZero - 5.6.2008, 09:16
PM MAIL   Вверх
mes
Дата 5.6.2008, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(SubZero @  5.6.2008,  09:01 Найти цитируемый пост)
она печатает на экране кучу ерунды и выводит в итоге в файл много мусора

вероятно у Last элемента next не равно NULL, поэтому прога не знает где конец списка..


--------------------
PM MAIL WWW   Вверх
SubZero
Дата 5.6.2008, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.6.2008

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



Цитата(mes @  5.6.2008,  09:38 Найти цитируемый пост)
вероятно у Last элемента next не равно NULL, поэтому прога не знает где конец списка.. 


Нет, дело явно не в этом. Ведь я беру простейший случай (1 элемент в списке), тогда срабатывает

Код

if (ptrFirst==NULL) //если списка еще нет
        {
            ptrLast->previous = NULL;
            ptrFirst = ptrLast;
            ptrLast->next = NULL;
            ptrCurrent = ptrFirst;
        }


то есть ptrLast->next == NULL. К тому же эта ошибка появляется только при замене cout() на printf() .. Мистика какая-то  smile 
PM MAIL   Вверх
mes
Дата 5.6.2008, 09:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



глянул код : 
Цитата(SubZero)
Код

            ptrCurrent = ptrLast;    // устанавливаем последний элемент текущим
            ptrLast->previous = ptrCurrent; // предыдуший у последнего теперь указывает на последний ?!
            ptrCurrent->next = ptrLast; //  зачем эта строчка, ведь ptrCurrent == ptrLast
            ptrLast->next = NULL; // если следуюшей строчкой ты его обнуляешь

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

Это сообщение отредактировал(а) mes - 5.6.2008, 10:07


--------------------
PM MAIL WWW   Вверх
mes
Дата 5.6.2008, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



кстати, а под указатели структуры
struct car
{
     char *mark;
     char *colour;
     char *number;
}
память выделяется?



--------------------
PM MAIL WWW   Вверх
SubZero
Дата 5.6.2008, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.6.2008

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



Цитата(mes @  5.6.2008,  09:48 Найти цитируемый пост)
глянул код : 

Цитата(SubZero)


            ptrCurrent = ptrLast;    // устанавливаем последний элемент текущим
            ptrLast->previous = ptrCurrent; // предыдуший у последнего теперь указывает на последний ?!
            ptrCurrent->next = ptrLast; //  зачем эта строчка, ведь ptrCurrent == ptrLast
            ptrLast->next = NULL; // если следуюшей строчкой ты его обнуляешь






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


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

Код

if (ptrFirst==NULL) //если списка еще нет
        {
            ptrLast->previous = NULL;
            ptrLast->next = NULL;
            ptrFirst = ptrLast;
            ptrCurrent = ptrFirst;
        }
        else //список уже существует
        {
            ptrLast->previous = ptrCurrent;
            ptrCurrent->next = ptrLast;
            ptrLast->next = NULL;
            ptrCurrent = ptrLast;
        }



Цитата(mes @  5.6.2008,  10:06 Найти цитируемый пост)
кстати, а под указатели структуры
struct car
{
     char *mark;
     char *colour;
     char *number;
}
память выделяется?


Да, выделяю. Приведу текст всей программы, чтобы было точно ясно. Посмотри, пожалуйста, чувствую, там есть еще не одна ошибка smile

Код

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <iostream.h>

struct avto
{
    char mark[20];
    char colour[20];
    char number[20];
};
struct record
{
    avto car;
    record *previous;
    record *next;
};

int ShowMenu()
{
char s[22];
int n;
do
{
    clrscr();
    printf("\n Выберите необходимый пункт меню:");
    printf("\n 1. Ввод данных с клавиатуры и запись их в файл");
    printf("\n 2. Вывод данных из файла\n");
    gets(s);
    n=atoi(s);
}
while ((n<1) || (n>2));
clrscr();
return n;
}

//
void InputAuto(avto *&p, record *&ptrFirst, record *&ptrCurrent, record *&ptrLast)
{
char s[22];
int n;
do
{
clrscr();
printf("\nВведите количество автомобилей ");
gets(s);
n = atoi(s);
} while (!(n>0));
for (int i=0;i<n;i++)
{
    ptrLast=(record *)malloc(sizeof(record));
    do
    {
     printf("\nВведите марку автомобиля ");
     s[0] = 20;
     cgets(s);
    }
    while (!(strlen(s)));
    strcpy(p->mark, s+2);
    do
    {
        printf("\nВведите цвет автомобиля ");
        s[0] = 20;
        cgets(s);
    }
    while (!(strlen(s)));
    strcpy(p->colour, s+2);
    do
    {
        printf("\nВведите номер автомобиля ");
        s[0] = 20;
        cgets(s);
    }
    while (!(strlen(s)));
    strcpy(p->number, s+2);
    ptrLast->car = *p;
    printf("\n");
    //включаем запись в список
    if (ptrFirst==NULL) //списка еще нет
    {
        ptrLast->previous = NULL;
        ptrLast->next = NULL;
        ptrFirst = ptrLast;
    }
    else //список уже существует
    {
        ptrCurrent = ptrFirst;
        //просмотр списка - поиск места для новой записи
        while (ptrCurrent)
        { if (strcmp(ptrLast->car.mark,ptrCurrent->car.mark)<0)
          {  //вставка новой записи перед ptrCurrent
             if (ptrFirst == ptrCurrent) //начало списка
             {
            ptrLast->previous = NULL;
            ptrFirst = ptrLast;
             }
             else  //вставка между записями
             {
            ptrCurrent->previous->next = ptrLast;
            ptrLast->previous = ptrCurrent->previous;
             }
          ptrCurrent->previous = ptrLast;
          ptrLast->next = ptrCurrent;
          break;//выход из цикла просмотра списка
          }
        if (ptrCurrent->next == NULL)
        {  //включаем запись в конец списка
           ptrLast->next = NULL;
           ptrLast->previous = ptrCurrent;
           ptrCurrent->next = ptrLast;
           break;
        }
        ptrCurrent = ptrCurrent->next;
         }  //конец цикла просмотра списка
    }  //включение записи выполнено

}
}

//сохранение данных из списка в файл
int SaveAutos(record *&ptrFirst, record *&ptrCurrent, record *&ptrLast)
{
char path[30];
FILE *ptrFile;
printf("\n Введите название файла, в который будет сохранен список ");
gets(path);
if ((ptrFile=fopen(path,"w"))==NULL)
{
    puts("Не могу открыть файл \n");
    exit(1);
}
// запись в файл осуществляем полями
ptrCurrent=ptrFirst;
while (!(ptrCurrent==NULL))
{
    fprintf(ptrFile,"%s %s %s\n",ptrCurrent->car.mark,ptrCurrent->car.colour, ptrCurrent->car.number);
    ptrCurrent=ptrCurrent->next;
}
// в конце файла - спецкод '***'
fprintf(ptrFile,"***\n");
fclose(ptrFile);
return 0;
}

//перезапись списка из файла в динамическую память
void LoadAutos(avto *&p, record *&ptrFirst, record *&ptrCurrent, record *&ptrLast)
{
FILE *ptrFile;
char strFileString[40], path[30];
//открытие файла для чтения
printf("\nВведите название файла из которого будут считываться данные ");
gets(path);
if ((ptrFile=fopen(path,"r"))==NULL)
{
    puts("Не могу открыть файл \n");
    exit(1);
}
ptrFirst = NULL;
do
{
    // чтение из файла по полям пока не дошли до символа завершения "*"
    fscanf(ptrFile,"%s",strFileString);
    if (strFileString[0]!='*')
    {
        //выделение памяти под новый элемент
        ptrLast=(record *)malloc(sizeof(record));
        strcpy(p->mark,strFileString);
        fscanf(ptrFile,"%s %s\n",&(p->colour),&(p->number));
        ptrLast->car = *p;
        if (ptrFirst==NULL) //если списка еще нет
        {
            ptrLast->previous = NULL;
            ptrLast->next = NULL;
            ptrFirst = ptrLast;
            ptrCurrent = ptrFirst;
        }
        else //список уже существует
        {
            ptrLast->previous = ptrCurrent;
            ptrCurrent->next = ptrLast;
            ptrLast->next = NULL;
            ptrCurrent = ptrLast;
        }
    }
} while (strFileString[0]!='*');
fclose(ptrFile); //закрытие файла
}

//вывод элементов списка на экран
void ShowAuto(avto &car)
{
    cout<<car.mark<<"\n";
    cout<<car.colour<<"\n";
    cout<<car.number<<"\n";

}
// тело основной функции
int main()
{
    avto *p=(avto *)malloc(sizeof(avto));
    record *ptrFirst, *ptrLast, *ptrCurrent;
    int n;
    n = ShowMenu();
    switch(n)
    {
    case 1:
        {
            //ввод данных
            InputAuto(p, ptrFirst, ptrCurrent, ptrLast);
            // вывод содержимого списка
            free(p);
            ptrCurrent = ptrFirst;
            while (ptrCurrent)
            {
               ShowAuto(ptrCurrent->car);
               ptrCurrent=ptrCurrent->next;
            }
            SaveAutos(ptrFirst, ptrCurrent, ptrLast);
            return(0);
            break;
        }
    case 2:
        {
            //загрузка данных из списка
            LoadAutos(p, ptrFirst,ptrCurrent, ptrLast);
            //печать списка
            ptrCurrent = ptrFirst;
            while (ptrCurrent)
            {
               ShowAuto(ptrCurrent->car);
               ptrCurrent=ptrCurrent->next;
            }
            free(p);
            getche();
            return(0);
            break;
        }
    }
}






Это сообщение отредактировал(а) SubZero - 5.6.2008, 10:24
PM MAIL   Вверх
mes
Дата 5.6.2008, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250




Цитата(SubZero @  5.6.2008,  10:23 Найти цитируемый пост)
  ptrLast->car = *p;

тут присваевается содержимое по указателю p, но не надо забывать что там хранятся указатели (char *mark;   char *colour;     char *number;)
и происходит просто присвоение этих указателей, а не копирование содержимого той памяти. т.е. в результате все записи списка указывают на одну и ту же память ( avto *p=(avto *)malloc(sizeof(avto));)

п.с. зря не прислушиваешься к совету :
Цитата(mes @  5.6.2008,  09:48 Найти цитируемый пост)
поэтому для начала выдели весь код  со списком в отдельные функции

сразу станет видно что к чему


--------------------
PM MAIL WWW   Вверх
SubZero
Дата 5.6.2008, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.6.2008

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



Цитата(mes @  5.6.2008,  10:59 Найти цитируемый пост)


 ptrLast->car = *p;

тут присваевается содержимое по указателю p, но не надо забывать что там хранятся указатели (char *mark;   char *colour;     char *number;)
и происходит просто присвоение этих указателей, а не копирование содержимого той памяти. т.е. в результате все записи списка указывают на одну и ту же память ( avto *p=(avto *)malloc(sizeof(avto));)

А как сделать правильно?


Цитата(mes @  5.6.2008,  10:59 Найти цитируемый пост)
п.с. зря не прислушиваешься к совету :

Цитата(mes @  5.6.2008,  09:48 )
поэтому для начала выдели весь код  со списком в отдельные функции

сразу станет видно что к чему 


Я не против, но хотелось бы обойтись без этого))

PM MAIL   Вверх
mes
Дата 5.6.2008, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(SubZero @  5.6.2008,  11:10 Найти цитируемый пост)
А как сделать правильно?

Цитата(SubZero @  5.6.2008,  11:10 Найти цитируемый пост)
Я не против, но хотелось бы обойтись без этого))

если не против (будем считать что после запятой ничего не написано)  тогда

для начала создай структуру
Код

struct list_t
{ record * pFirst;
  record *pLast;
};

и функции
Код

avto   newAuto (char *mark,  char *colour, char *number);// результат указатель на выделенную память для всех указателей и копией входных значений
void   delAvto (avto & car); // все удаляет 

record * list_new_record ()    -по созданию нового элемента 
record * list_push_back (list_t& list) -используя предыдушую функцию она помешает новую запись в конец списка

тогда 
добавление нового элемента будет выглядить так

Код

list_push_back(list)->car = newAvto (mark, colour, number);


Это сообщение отредактировал(а) mes - 5.6.2008, 12:01


--------------------
PM MAIL WWW   Вверх
SubZero
Дата 5.6.2008, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 49
Регистрация: 3.6.2008

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



Цитата(mes @ 5.6.2008,  11:47)
Цитата(SubZero @  5.6.2008,  11:10 Найти цитируемый пост)
А как сделать правильно?

Цитата(SubZero @  5.6.2008,  11:10 Найти цитируемый пост)
Я не против, но хотелось бы обойтись без этого))

если не против (будем считать что после запятой ничего не написано)  тогда

для начала создай структуру
Код

struct list_t
{ record * pFirst;
  record *pLast;
};

и функции
Код

avto * newAuto (char *mark,  char *colour, char *number);// результат указатель на выделенную память для всех указателей и копией входных значений
void   delAvto (avto *); // все удаляет

record * list_new_record ()    -по созданию нового элемента 
record * list_push_back (list_t& list) -используя предыдушую функцию она помешает новую запись в конец списка

тогда 
добавление нового элемента будет выглядить так

Код

list_push_back(list)->car = newAvto (mark, colour, number);

Хорошо, после обеда начну трудиться над этими функциями  smile 
Хотя жутко леееень smile
Но я буду стараться!
PM MAIL   Вверх
mes
Дата 5.6.2008, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(SubZero @  5.6.2008,  12:00 Найти цитируемый пост)
Хотя жутко леееень 

 а нам наверно жуть как охота лазять в дебрях запутанного кода??  smile 

Цитата(SubZero @  5.6.2008,  12:00 Найти цитируемый пост)
Но я буду стараться! 

 smile 

p.s. я свой предыдуший пост подправил..


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

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

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

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

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


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

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


 




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


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

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