Ошибка SegFault, но связанный список работает правильно - PullRequest
1 голос
/ 16 января 2020

Мне бы очень хотелось узнать, почему программа компилируется и работает без сбоев или плохих результатов, просто «SegFault» в самом конце программы (а также другой нежелательный результат). Задача программы - разместить отдельные буквы в связанном списке в алфавитном порядке. Такая структура должна содержать количество обнаруженных писем и, конечно же, само письмо.

ВХОД

swag

ВЫХОД

aagsw Letter: a Frequency: 1 Letter: g Frequency: 1 Letter: s Frequency: 1 Letter: w Frequency: 1 Letter: � Frequency: 194 Segmentation Fault

Не должно быть так, как должно быть:

aagsw Letter: a Frequency: 1 Letter: g Frequency: 1 Letter: s Frequency: 1 Letter: w Frequency: 1

( Капитан Очевидность, спасибо позже)

Я дам вам код.

Проблема решена

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

typedef char string[30];

typedef struct nodo{
  char chara;
  int freq;
  struct nodo *next;
}Nodo;

typedef Nodo *Lista;

typedef struct{
  int value;
  char chara;
  int freq;
}Lettera;

Lista head;

void Creator(string stringa){

  Lettera letter[26];

  for(int i=0; i < strlen(stringa); i++){ //unnecessary part
    for(int j=0; j < strlen(stringa)-1; j++){
      if((int) stringa[j] > (int) stringa[j+1]){
        char tmp=stringa[j+1];
        stringa[j+1] = stringa[j];
        stringa[j] = tmp;
      }
    }
  }

  printf("%s\n",stringa);
  int k=97;
  for(int i=0; i<26; i++){  //initializing auxiliary struct
    letter[i].chara = (char) k;
    letter[i].value = k;
    letter[i].freq = 0;
    k++;
  }

  for(int i=0; i < strlen(stringa); i++){
    for(int j=0; j<26; j++){
      if(letter[j].chara == stringa[i]){
        letter[j].freq++;
      }
    }
  }

  Lista temp=NULL; //forgot to initialize

  for(int i=25; i>=0; i--){ //wrong index was i=26
    if(letter[i].freq>0){
      head=(Lista) malloc (sizeof(Nodo));
      head->chara = letter[i].chara;
      head->freq = letter[i].freq;
      head->next = temp;
      temp = head;
    }
  }
  while(head != NULL){
    printf("Letter: %c \tFrequency: %d\n", head->chara, head->freq);
    head = head->next;
  }
}

int main(){
  string stringa;
  scanf("%s",stringa);
  Creator(stringa);
}

1 Ответ

1 голос
/ 16 января 2020

Чао, Хабрас.

Мы, начинающие, должны помогать друг другу. :)

Ваш подход слишком сложен. Нет необходимости сортировать введенную строку. Это список, который должен располагать буквы по порядку при добавлении в список.

Более того, есть ошибки. Например, вы объявили массив letter как

Lettera letter[26];

Итак, допустимый диапазон индексов - [0, 26). Однако в этом l oop

  for(int i=26; i>=0; i--){
    if(letter[i].freq>0){
      head=(Lista) malloc (sizeof(Nodo));
      head->chara = letter[i].chara;
      head->freq = letter[i].freq;
      head->next = temp;
      temp = head;
    }
  }

вы пытаетесь получить доступ к несуществующему элементу с индексом, равным 26.

Вот демонстрационная программа, которая показывает, как буквы может быть добавлен в список.

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

typedef struct nodo
{
    char chara;
    size_t freq;
    struct nodo *next;
} Nodo;

typedef Nodo *Lista;

void initialize( Lista *lista, const char *s )
{
    for ( ; *s; ++s )
    {
        char c = *s;

        if ( isalpha( ( unsigned char )c ) )
        {
            c = tolower( ( unsigned char )c );

            Nodo **nodo = lista;

            while ( *nodo != NULL && ( *nodo )->chara < c )
            {
                nodo = &( *nodo  )->next;
            }

            if ( *nodo == NULL || c < ( *nodo )->chara )
            {
                Nodo *current = malloc( sizeof( Nodo ) );
                current->chara = c;
                current->freq = 1;
                current->next = *nodo;
                *nodo = current;
            }
            else
            {
                ++( *nodo )->freq;
            }
        }           
    }
}

int main(void) 
{
    enum { N = 100 };

    Lista lista = NULL;

    char s[N];
    s[0] = '\0';

    printf( "Enter a text: " );

    fgets( s, sizeof( s ), stdin );

    initialize( &lista, s );

    for ( Nodo *current = lista; current != NULL; current = current->next )
    {
        printf( "{ %c: %zu } ", current->chara, current->freq );
    }

    puts( "NULL" );

    return 0;
}

Его вывод может выглядеть как

Enter a text: Buona notte Habras
{ a: 3 } { b: 2 } { e: 1 } { h: 1 } { n: 2 } { o: 2 } { r: 1 } { s: 1 } { t: 2 } { u: 1 } NULL
...