Связанные списки: словарь

Рейтинг: 1Ответов: 1Опубликовано: 01.04.2011

Дан файл. Надо считать из него слова и вывести на экран (не повторяя слова) и их количество.

У меня появилась проблема: список заполняется неправильно, и программа вылетает)

У меня получился следующий код:

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

struct elem{ //Элемент списка
    char word[255];
    int count;
    elem *next;
};

elem * GDFF(char filename[], elem *dict); //Возвращает указатель на словарь. Get Dictionary From File. Получает словарь из файла.
void printD(elem *dict); //Вывод на экран
elem* addW(char word[255],elem *dict);
elem *searchW(char t[],elem *dict);
elem* freeD(elem *dict);
void strcpy(char a[255],char b[]);

void main(){
    char fn[]=""; //Путь к файлу
    elem *dict=NULL;   //Указатель на список
    dict=NULL;

    printf("Enter filename:\n");
    scanf("%s",&fn);

    dict=GDFF(fn,dict);
    printD(dict);
    dict=freeD(dict);
    getch();
}

void printD(elem *dict){
    while(dict!=NULL){
        printf("%s : %d\n",dict->word,dict->count);
        dict=dict->next;
    }
}

elem * GDFF(char filename[], elem *dict){
    FILE *f=fopen(filename, "r");
    elem *pointer;
    char t[255];
    while(!feof(f)){
        fscanf(f,"%s",&t);
        if(pointer=searchW(t,dict)){
            pointer->count++;
            printf("plussed %s",pointer->word);
        }else{
            dict=addW(t,dict);
            printf("added %s",dict->word);
        }
        //printf("%s\n",t);
    }
    return dict;
}

elem *searchW(char t[],elem *dict){
    elem *p=dict;
    while(p!=NULL&&p->word!=t){
        p=p->next;
    }
    return p;
}

elem* addW(char word[255],elem *dict){
    elem *p=dict;
    elem *t=(elem*)malloc(sizeof(elem));
    t->count=1;
    strcpy(t->word,word);
    t->next=NULL;
    if(p!=NULL){
        while(p->next!=NULL){
            p=p->next;
        }
        p->next=t;
    }else{
        return t;
    }
    return dict;
}

elem* freeD(elem *dict){
    while(dict!=NULL){
    elem *t=dict; 
    dict=dict->next;
    free(t);
    }
    return NULL;
}

void strcpy(char a[255],char b[]){
    for(int i=0; i<255; i++){
        a[i]=b[i];
    }
}

Код исправлен получилось следующее

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

struct elem{ //Элемент списка
    char word[255];
    int count;
    elem *next;
};

elem * GDFF(char filename[], elem *dict); //Возвращает указатель на словарь. Get Dictionary From File. Получает словарь из файла.
void printD(elem *dict); //Вывод на экран
elem* addW(char word[255],elem *dict);
elem *searchW(char t[],elem *dict);
elem* freeD(elem *dict);
void strcpy(char a[255],char b[]);
bool equal(char a[255],char b[]);

void main(){
    char fn[255]=""; //Путь к файлу
    elem *dict=NULL;   //Указатель на список
    dict=NULL;

    printf("Enter filename:\n");
    scanf("%s",&fn);

    dict=GDFF(fn,dict);
    printD(dict);
    dict=freeD(dict);
    getch();
}

void printD(elem *dict){
    while(dict!=NULL){
        printf("%s : %d\n",dict->word,dict->count);
        dict=dict->next;
    }
}

elem * GDFF(char filename[], elem *dict){
    FILE *f=fopen(filename, "r");
    elem *pointer;
    char t[255];
    while(!feof(f)){
        fscanf(f,"%s",&t);
        if(pointer=searchW(t,dict)){
            pointer->count++;
        }else{
            dict=addW(t,dict);
            printf("added %s",dict->word);
        }
    }
    return dict;
}

elem *searchW(char t[],elem *dict){
    elem *p=dict;
    while(p!=NULL&&!equal(p->word,t)){
        p=p->next;
    }
    return p;
}

elem* addW(char word[255],elem *dict){
    elem *p=dict;
    elem *t=(elem*)malloc(sizeof(elem));
    t->count=1;
    strcpy(t->word,word);
    t->next=NULL;
    if(p!=NULL){
        while(p->next!=NULL){
            p=p->next;
        }
        p->next=t;
    }else{
        return t;
    }
    return dict;
}

elem* freeD(elem *dict){
    while(dict!=NULL){
    elem *t=dict; 
    dict=dict->next;
    free(t);
    }
    return NULL;
}

void strcpy(char a[255],char b[]){
    for(int i=0; i<255; i++){
        a[i]=b[i];
    }
}

bool equal(char a[255],char b[])
{
    for(int i=0; i<255&&a[i]&&b[i]; i++){
        if(a[i]!=b[i]){
            return false;
        }
    }
    return true;
}

Ответы

▲ 4Принят

"Stack around the variable 'fn' was corrupted" - такая ошибка обычно возникает при выходе за границы массива. Что у Вас и происходит.

char s[]="qwerty";

Если создается массив таким методом, то размер массива = количеству символов в данной строке + нуль-символ, в вашем примере она пустая => 1 символ, да и тот служебный. Введите размер данного массива, и все будет хорошо =)
Это то что касается вылета программы.

p->word!=t

Строки нельзя так сравнивать, сравнивать надо самостоятельно, просматривая все символы, я не помню стандартную функцию, но и такая сойдет

bool equal(char a[],char b[])
{
    int i;
    for(i=0;a[i]&&b[i];i++)
        if(a[i]!=b[i]) return false;
    return (!a[i]&&!b[i]); 
}