Устранение ошибок, связанных с циклическим списком времени компиляции - PullRequest
0 голосов
/ 10 октября 2011

Хорошо, я получаю эти ошибки при компиляции с gcc:

prelab6.h: In function âinsertHeadCircularâ:
prelab6.h:45: error: incompatible types in assignment
prelab6.h:46: error: incompatible types in assignment
prelab6.c: At top level:
prelab6.c:41: warning: data definition has no type or storage class
prelab6.c:41: warning: parameter names (without types) in function declaration
prelab6.c:41: error: conflicting types for âprintInOrderâ
prelab6.h:81: error: previous definition of âprintInOrderâ was here
prelab6.c:42: warning: data definition has no type or storage class
prelab6.c:42: warning: parameter names (without types) in function declaration
prelab6.c:42: error: conflicting types for âprintReverseâ
prelab6.h:112: error: previous definition of âprintReverseâ was here

Я пробовал и пытался, но безуспешно, чтобы исправить эти ошибки. Спасибо за любую помощь.

Вот мой файл .c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "my.h"

int main ( int argc, char **argv )
{

char firstname[100];
char lastname[100];
int monthsEmployed;

FILE *fptr;
fptr = fopen(argv[1], "r");

if (fptr == NULL)
    printf ("Incorrect file reading!");

if (argc != 2)
    printf ("Incorrect number of arguments!");


employeeInfo *insert;
insert = malloc(sizeof(employeeInfo));
employeeList *head;
head = NULL;


while(!feof(fptr))
{   
    fscanf (fptr, "%100s %100s %d", firstname, lastname, &monthsEmployed);

    strcpy(insert->firstname, firstname);
    strcpy(insert->lastname, lastname); 
    insert->monthsEmployed = monthsEmployed;

    head = insertHeadCircular(head, insert);
}
}

printInOrder(head); // display the linked list
printReverse(head); // display the linked list in reverse

И мой файл .h (обратите внимание, что комментарии закомментированы, потому что я пытался по-другому, но безрезультатно):

typedef struct employeeInfo{
        char firstname[100];
        char lastname[100];
        int monthsEmployed;
}employeeInfo;

//Struct containing pointers to the next and previous used to make a circular linked list 
typedef struct list{
                employeeInfo emp;
                struct list *next;
                struct list *previous;
}employeeList;

employeeList *insertHeadCircular(employeeList *head, employeeInfo *emp);
void printInOrder(employeeList head);
void printReverse(employeeList head);

employeeList *insertHeadCircular(employeeList *head, employeeInfo *emp)
{
    employeeList *theprevious = head;
    employeeList *current;
    employeeList *thenext = head;
    current = malloc(sizeof(employeeList));
    employeeInfo *employee;

    if(thenext==NULL)
    {
        current->next = current;
        current->previous = current;
    }

    else
    {
        current->next = thenext;
        thenext->previous = current;

        while(theprevious->next != thenext)
        {
            theprevious = theprevious->next;
        }
        current->previous = theprevious;
        theprevious->next = current;
    }

    current->emp = (employeeInfo *)malloc(sizeof(employeeInfo));
    employee = current->emp;
    employee = malloc(sizeof(employeeInfo));
    strcpy(employee->firstname, emp->firstname);
    strcpy(employee->lastname, emp->lastname);
    employee->monthsEmployed = emp->monthsEmployed;

    /*
    employeeList *newcell, *first = head;

    if(head == NULL)
    {
        newcell = (struct list *)malloc(sizeof(struct list));
        strcpy(newcell->firstname, emp->firstname);
        strcpy(newcell->lastname, emp->lastname);
        newcell->monthsEmployed = emp->monthsEmployed;
        return newcell;
    }

    while(head->next != first)
    {
        head = head->next;
    }

    newcell = (struct list *)malloc(sizeof(struct list));
    head->next = newcell;
    strcpy(newcell->firstname, emp->firstname);
    strcpy(newcell->lastname, emp->lastname);
    newcell->monthsEmployed = emp->monthsEmployed;
    newcell->next = first;
    */
return current;
}


void printInOrder(employeeList head)
{
    /*employeeInfo *first = head;

    if (head == NULL)
        {
        printf("The circularly linked list is empty!\n");
        return;
        }

        do
        {

        printf("%s %s %d\n", emp.firstname, emp.lastname, head.monthsEmployed);

        head = head->next;
        } while(head != first);
*/
    /*employeeInfo current = head;
    employeeInfo start = head;
    int loop = 0;
    printf("--------------\n");
    while(current != start || loop==0)
    {
    loop++;
    printf("Employee: %s %s\nMonths Employed: %d", current->firstname, current->lastname, current->monthsEmployed);
    printf("--------------\n");
    current=current->next;
    }*/
}

void printReverse(employeeList head)
{/*
    employeeList current = head
    employeeInfo start = head
    int theloop=0;
    printf("--------------\n");
    while(current! = start || loop==0)
    {
    loop++;
    printf("Employee: %s %s\nMonths Employed: %d", current->firstname, current->lastname, current->monthsEmployed);
    printf("--------------\n");
    current=current->previous;
    }*/
}

РЕДАКТИРОВАННАЯ ПРОГРАММА

Ошибка:

file.c: In function âmainâ:
file.c:37: error: incompatible type for argument 2 of âinsertHeadCircularâ

.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "file.h"

int main ( int argc, char **argv )
{

char firstname[100];
char lastname[100];
int monthsEmployed;

FILE *fptr;
fptr = fopen(argv[1], "r");

if (fptr == NULL)
    printf ("Incorrect file reading!");

if (argc != 2)
    printf ("Incorrect number of arguments!");


employeeInfo *insert;
insert = malloc(sizeof(employeeInfo));
employeeList *head;
head = NULL;


while(!feof(fptr))
{   
    fscanf (fptr, "%100s %100s %d", firstname, lastname, &monthsEmployed);

    strcpy(insert->firstname, firstname);
    strcpy(insert->lastname, lastname); 
    insert->monthsEmployed = monthsEmployed;

    head = insertHeadCircular(head, insert);
}

printInOrder(head); // display the linked list
printReverse(head); // display the linked list in reverse
}

.h:

typedef struct employeeInfo{
    char firstname[100];
    char lastname[100];
    int monthsEmployed;
}employeeInfo;

typedef struct list{
    employeeInfo emp;
    struct list *next;
    struct list *previous;
}employeeList;
    typedef employeeList *listnode;

employeeList *insertHeadCircular(employeeList *head, employeeInfo emp);
void printInOrder(employeeList *head);
void printReverse(employeeList *head);



employeeList *insertHeadCircular(employeeList *head, employeeInfo emp)
{
    listnode newPtr;
    listnode firstPtr;
    listnode tempPtr;

    newPtr = (employeeList *)malloc(sizeof(employeeList));

    strcpy(newPtr->emp.firstname, emp.firstname);
    strcpy(newPtr->emp.lastname, emp.lastname);
    newPtr->emp.monthsEmployed = emp.monthsEmployed;

    if(head == NULL)
    {   
        newPtr->next = newPtr;
        newPtr->previous = newPtr;
        head = newPtr;
        firstPtr = newPtr;

    }
    else
    {
        tempPtr = firstPtr;
        newPtr->next = tempPtr;
        tempPtr->previous = newPtr;

        newPtr->previous = head;
        head->next = newPtr;
        firstPtr = newPtr;
    }
    return head;
}
void printInOrder(employeeList *head)
{
        listnode currentPtr = head;
        do
    {
            printf("%s %s %d\n",currentPtr->emp.firstname, currentPtr->emp.lastname, currentPtr->emp.monthsEmployed);
        currentPtr= currentPtr->previous;
    }
    while(currentPtr !=head);
}
void printReverse(employeeList *head)
{
        listnode currentPtr = head->next;
        do        
    {
        printf("%s %s %d\n",currentPtr->emp.firstname, currentPtr->emp.lastname, currentPtr->emp.monthsEmployed);
        currentPtr = currentPtr->next;
    }
    while(currentPtr != head->next);        
}

1 Ответ

1 голос
/ 10 октября 2011

В вашей функции insertHeadCircular() вы обрабатываете emp член employeeList, как если бы это был employeeInfo *. Например, вы объявляете:

employeeInfo *employee;

но потом сделаем это:

employee = current->emp;

Однако ваш тип employeeList содержит экземпляр employeeInfo, а не указатель на него:

typedef struct employeeInfo{
        char firstname[100];
        char lastname[100];
        int monthsEmployed;
}employeeInfo;
/* ... */
typedef struct list{
                employeeInfo emp;    /* see? Not a pointer. */
                struct list *next;
                struct list *previous;
}employeeList;

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

Скорее всего, ваши printInOrder() и printReverse() функции должны принимать employeeList * аргументы, а не employeeList, а также ... и вы должны проверить код, который вы используете для них, чтобы убедиться, что вы этого не сделаете путать два в любом месте.

Также неплохо определить свои функции где-то, кроме файла заголовка, например, в отдельном .c исходном файле. Файл заголовка должен просто содержать прототипы функций, макросы и другие объявления, которые могут понадобиться для других исходных файлов; там вам не нужны тела функций, так как компоновщик может найти их в объектных файлах, созданных из ваших других источников. Подобное определение функций в заголовочных файлах вызовет бесконечные головные боли, когда заголовочный файл #include редактируется более чем одним файлом.


Ошибка, которую вы получаете с вашим обновленным кодом, file.c:37: error: incompatible type for argument 2 of âinsertHeadCircularâ указывает на то, что тип аргумента, который вы передаете insertHeadCircular(), не тот тип, который вы указали в его объявлении - и это правда. Вы объявили и определили эту функцию, чтобы принять employeeInfo в качестве второго аргумента:

employeeList *insertHeadCircular(employeeList *head, employeeInfo emp)

... но в main() вместо него передается указатель:

employeeInfo *insert;
...
    head = insertHeadCircular(head, insert);

Так что вам нужно поменять одно или другое. Либо разыменуйте insert при вызове функции из main, либо измените insertHeadCircular(), чтобы вместо него взять указатель (и соответственно обновите тело). Последнее, вероятно, лучше, так как позволяет избежать копирования всей структуры в стек при вызове функции.

Некоторые другие вещи, на которые следует обратить внимание:

Вы действительно должны проверить возврат из scanf() в вашем цикле в main(). Это позволит вам узнать, все ли поля были прочитаны; Прямо сейчас, если это не так, ваша программа просто продолжает работать с тем мусором, который уже имел переменные (например, с тем, что читалось на предыдущей итерации, возможно). Проверка других возвращаемых значений (например, возврат из malloc()) также является хорошей идеей, но в этом случае особенно важно возвращение scanf().

Вы также не освобождаете insert в конце вашей программы; ОС (почти наверняка) очистит ее при выходе из программы, но хорошей практикой является сделать это самостоятельно, когда вы закончите с ней. Однако, как вы его используете, вам все равно не нужно было его динамически размещать; Вы могли бы просто объявить employeeInfo и взять его адрес (работает в любом случае).

...