Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.03.2013, 20:30   #1
Joose
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 67
По умолчанию Проблема с односвязным циклом

Привет. Есть некоторая функция, написанная на Си, которая считывает в односвязный список структур некоторые данные, в результате чего каждый элемент списка имеет вид:

строка
число
указатель на следующее

Код всей программы приводить не буду, опишу только функцию, которая выполняет считывание. start - глобальная переменная, имеющая смысл начала списка, в которую записывается самая первая по алфавиту карточка, и в последующем значение в start меняться не должно:

Код:
void loadDict(const char *name_file)
{
    int freq = 0;
    char word[25];
    Card *newPtr, *current = NULL;
    FILE *file;
    start = NULL;                                   /*Очистить заглавную карточку, т.к. возможно нахождение в ней ненужного мусора*/
    file = fopen(name_file, "r");

    while(!feof(file))
    {
        newPtr = (Card*)malloc(sizeof(Card));       /*Выделение памяти для создания очередной карточки*/
        fscanf(file, "%s%d", word, &freq);          /*Считать из файла очередное слово и число его вхождений*/
        newPtr->name = word;                        /*Записать считанное слово во временное хранилище*/
        newPtr->ent = freq;                         /*Записать считанное число в временное хранилище*/
        newPtr->next = NULL;                        /*Указателю на следующее присвоить NULL*/

        if(start == NULL)                           /*Если это первое слово, то записать структуру из хранилища в первый элемент списка*/
        {
            start = newPtr;
            printf("%-15s\t%3d\n", start->name, start->ent);
        }
        
        else                                        //Иначе это второе и более слово, нужно записать его в другую карточку
        {
            current = newPtr;
            printf("%-15s\t%3d\n", current->name, current->ent);
            current = current->next;
        }

    }

            printf("%-15s\t%3d\n", start->name, start->ent);
    fclose(file);
}
Проблема в том, что значение в карточке start меняется на протяжении выполнения всего цикла по считыванию из файла. Хотя в условии указано, что считывать в start необходимо только один раз, когда start == NULL. По сути мне необходимо, чтобы в start хранилась первая карточка списка, указатель на следующее из start указывал на current. Дальнейшая вставка карточек должна выполняться при помощи current, не передвигая start. Помогите разобраться, пожалуйста.
Joose вне форума Ответить с цитированием
Старый 26.03.2013, 21:24   #2
Joose
Пользователь
 
Регистрация: 16.10.2011
Сообщений: 67
По умолчанию

Ошибся в названии темы, подразумевался односвязный список
Joose вне форума Ответить с цитированием
Старый 27.03.2013, 00:57   #3
kineziz
Форумчанин
 
Регистрация: 22.12.2011
Сообщений: 378
По умолчанию

Тут в коде есть непонятка:
Код:
newPtr = (Card*)malloc(sizeof(Card));       /*Выделение памяти для создания очередной карточки*/
        fscanf(file, "%s%d", word, &freq);          /*Считать из файла очередное слово и число его вхождений*/
        newPtr->name = word;                        /*Записать считанное слово во временное хранилище*/
        newPtr->ent = freq;                         /*Записать считанное число в временное хранилище*/
        newPtr->next = NULL;                        /*Указателю на следующее присвоить NULL*/

        if(start == NULL)                           /*Если это первое слово, то записать структуру из хранилища в первый элемент списка*/
        {
            start = newPtr;
            printf("%-15s\t%3d\n", start->name, start->ent);
        }
        
        else                                        //Иначе это второе и более слово, нужно записать его в другую карточку
        {
            current = newPtr;
            printf("%-15s\t%3d\n", current->name, current->ent);
            current = current->next;
        }
Вы инициализируете
Код:
newPtr->next
нулем, но затем вы приравниваете
Код:
current = current->next;
В итоге получается что строчка
Код:
current = current->next;
эквивалентна строке
Код:
current = NULL
По идеи должно быть так:
Код:
current->next = newPtr
Это уже логически верно, т.к. устанавливается связь между current и новым элементом
Большинство хороших программистов делают свою работу не потому, что ожидают оплаты или признания, а потому что получают удовольствие от программирования.

Последний раз редактировалось kineziz; 27.03.2013 в 01:00.
kineziz вне форума Ответить с цитированием
Старый 27.03.2013, 01:18   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Попробуйте:
Код:
if(start == NULL)
{
    current = start = newPtr;
    printf("%-15s\t%3d\n", start->name, start->ent);
} else {
    current->next = newPtr;
    current = newPtr;
    printf("%-15s\t%3d\n", current->name, current->ent);
}
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с циклом на СИ. hgfdd Помощь студентам 1 30.09.2012 15:54
Проблема с циклом DsDevis Паскаль, Turbo Pascal, PascalABC.NET 8 24.01.2011 00:01
проблема с циклом kiborgdelto Помощь студентам 1 16.10.2010 19:46
проблема с циклом Dima_D Общие вопросы Delphi 5 04.08.2010 16:41
Проблема с циклом.. POPOV Помощь студентам 3 29.04.2008 18:36