2014-09-23 2 views
-2

Я пытаюсь создать программу, которая считывает в текстовом файле в следующем формате:Моя Linked Список программ не будет работать

Smith, John  
Johnson, Harry  
Clark, David 

(Это может продолжаться бесконечно, и там не нужно быть пустой строкой между каждым именем, которое я просто написал для этого способа для ясности)

Каждая строка текстового файла содержит: last name, first name. Связанный список должен хранить каждое имя и фамилию в качестве узла имени. Я полагаю, что моя общая архитектура должна работать, однако, по мере выполнения программы, кажется, что переменные, такие как pCurrent и pHead, перегружены без переустановки. Я остался с перепутанным Linked List, и я никогда не видел ничего подобного. Может ли кто-нибудь обнаружить недостаток в моей архитектуре или что-то еще, что заставляет эту программу работать не так, как ожидалось. Благодаря

#include <stdlib.h> 
#include <stdio.h> 

#include <string.h> 

struct nameNode { 
    char* first; 
    char* last; 
    struct nameNode* pNext; 
    struct nameNode* pPrev; 
}; 

struct nameNode* pHead, *pLast; 
char firstName[50], lastName[50]; 

void insert_end(char* first, char* last) { 
    struct nameNode* var = NULL, *temp = NULL; 

    var = (struct nameNode*)malloc(sizeof(struct nameNode)); 

    var->first = first; 
    var->last = last; 
    if (pHead == NULL) { 
     pHead = var; 
     pHead->pPrev = NULL; 
     pHead->pNext = NULL; 
     pLast = pHead; 
    } else { 
     pLast = pHead; 
     while (pLast != NULL) { 
      temp = pLast; 
      pLast = pLast->pNext; 
     } 

     pLast = var; 
     temp->pNext = pLast; 
     pLast->pPrev = temp; 
     pLast->pNext = NULL; 
     printf("Phead is %s\n", pHead); 
    } 
} 

int main() { 
    char file[100]; 
    printf("Enter input file "); 
    scanf("%s", file); 
    FILE* in_file = fopen(file, "r"); 

    while (fscanf(in_file, "%s %s", lastName, firstName) != EOF) { 
     insert_end(lastName, firstName); 
    } 
} 
+0

Этот вопрос не соответствует теме, поскольку он не создает пример минимального, полного и проверяемого. – haccks

+1

Скопируйте эти три имени в текстовый файл и затем напишите адрес при появлении запроса и просмотрите связанный список. Это полный пример, верно? Также я могу добавить оператор печати, чтобы сообщить программисту, что pHead соответствует каждой итерации цикла while, если это поможет проблеме стать более очевидной? – user3451026

ответ

0

Читаешь свое имя в глобальную переменную и хранить адрес, где вы читаете его на сайте. Затем вы читаете новое имя в одну и ту же переменную - и снова сохраняете тот же адрес.

Изменить это в insert_end код

var->first = strdup (first); 
var->last = strdup (last); 

хранить копии из строк прочитанных в firstName и lastName.


Minor: как это, вы на самом деле есть неопределенное поведение. Вы проверяете, является ли pHead NULL, но вы никогда не инициализируете его. Убедитесь в том, чтобы установить его в NULL перед вызовом insert_end или просто инициализировать его как

struct nameNode* pHead = NULL, *pLast = NULL; 

Также незначительные: добавление узла без temp может быть сделано следующим образом. На самом деле вам не нужен цикл, потому что вы уже знаете, что pLast указывает на конец списка, но если вы хотите убедиться, что оно действительно, вы можете использовать тот факт, что для последнего nameNode его участник pNextдолжен быть NULL:

pLast = pHead; 
while (pLast->pNext != NULL) { 
    pLast = pLast->pNext; 
} 
pLast->pNext = var; 
pLast->pNext->pPrev = pLast; 
pLast->pNext->pNext = NULL; 
pLast = pLast->pNext; 

Также незначительные: избавиться от запятой, вставить это ближе к началу в insert_node:

if (first && first[0] && first[strlen(first)-1] == ',') 
    first[strlen(first)-1] = 0; 

Обратите внимание, что это удаляет запятую от аргумента называетсяfirst, что на самом деле является фамилией. Вы можете исправить это на протяжении всего кода.

Также также несовершеннолетний: ваш scanf не очень безопасен или не подлежит возмещению. Он может читать за пределами пространства хранения для каждой строки (49 символов), и вы проверяете конец файла, но не для несоответствия счетчика аргументов.

Это должно быть лучше:

while (fscanf(in_file, " %49[^,],%49s", lastName, firstName) == 2) { 
    insert_end(lastName, firstName); 
} 

- в качестве дополнительного бонуса, он также читает-то, игнорирует запятую.

+0

Life Saver, спасибо большое. Итак, чтобы понять, проблема была переменная область видимости? – user3451026

+0

Да, это было главное (хотя я бы не назвал это «областью»). Обязательно прочитайте мои небольшие заметки. – usr2564301

0

Я считаю, что вам нужно определить структуру NameNode следующим образом:

struct nameNode { 
    char[some_size] first; 
    char[some_size] last; 
    struct nameNode* pNext; 
    struct nameNode* pPrev; 
}; 

Или таНос пространство для первой и последней, когда вставить узел.

+0

Это, сам по себе, не исправляет, хотя он * мог *. Вы можете указать, какие еще изменения необходимо внести. – usr2564301

Смежные вопросы