Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Sorter słów w C

Ostatnio zmodyfikowano 2015-06-08 19:02
Autor Wiadomość
ziomal123456789
Temat założony przez niniejszego użytkownika
Sorter słów w C
» 2015-06-07 18:36:00
Witam
Otóż mam problem z napisaniem programu sorter słów w języku C. Program ma zapisywać pojedyncze słowa z klawiatury do pliku, następnie odczytać z te słowa z pliku, posortować alfabetycznie i na końcu zapisać do nowego pliku. Program na początku wydawał się banalny, ale zatrzymałem się na odczycie danych z pliku i zapisie ich do tablicy dynamicznej w celu posortowania. Prosiłbym o pomoc w poprawieniu kodu, szczególnie zależy mi na odczycie z pliku i zapisie do tablicy. Z resztą myślę, że sobie poradzę.
C/C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int podaj_dane();
void uzupelnijplik( int liczbaslow );
char ** tworztabliceslow( int liczbaslow );
char ** odczytzpliku( int liczbaslow );
void zwolnijpamiec( int liczbaslow, char ** tablicaslow );
void sortowanie( int liczbaslow, char ** tablicaslow );
void wypisz( int liczbaslow, char ** tablicaslow );
void zapisdopliku( int liczbaslow, char ** tablicaslow );

int main()
{
    int liczbaslow, i, j;
    liczbaslow = podaj_dane();
    uzupelnijplik( liczbaslow );
    char ** pustatablica = tworztabliceslow( liczbaslow );
    char ** tablicaslow = odczytzpliku( liczbaslow );
    for( i = 0; i < liczbaslow; i++ )
         printf( "%s\n", tablicaslow[ i ] );
   
    odczytzpliku( liczbaslow );
}

void uzupelnijplik( int liczbaslow ) //funkcja uzupelniajaca plik slowami
{
    int i;
    char slowo[ 20 ];
    FILE * fp;
    printf( "Podaj wyrazy. Po kazdym wcisnij enter \n" );
    if(( fp = fopen( "test.txt", "w" ) ) == NULL )
    {
        printf( "Nie moge otworzyc pliku test.txt do zapisu!\n" );
        exit( 1 );
    }
    for( i = 0; i < liczbaslow; i++ )
    {
        scanf( "%s", slowo );
        fprintf( fp, "%s\n", slowo );
    }
    fclose( fp );
};

int podaj_dane() //funkcja pobierajaca dane od uzytkownika
{
    int liczbaslow;
    printf( "Podaj liczbe wyrazow \n" );
    scanf( "%i", & liczbaslow );
    return liczbaslow;
}

char ** odczytzpliku( int liczbaslow ) //funkcja odczytujaca slowa z pliku
{
    int i, j;
    FILE * fp, * fb;
    char slowo[ 20 ];
    fp = fopen( "test.txt", "r" );
    char ** tablicaslow =( char ** ) malloc( liczbaslow * sizeof( char * ) );
    for( i = 0; i < liczbaslow; i++ )
    {
        tablicaslow[ i ] =( char * ) malloc( liczbaslow * sizeof( char ) );
        fscanf( fp, "%s\n", slowo );
        tablicaslow[ i ] = slowo;
    }
    fclose( fp );
    return tablicaslow;
   
}

char ** tworztabliceslow( int liczbaslow ) //funkcja tworzy pustą tablicę słów
{
    int i;
    char ** pustatablica =( char ** ) malloc( liczbaslow * sizeof( char * ) );
    for( i = 0; i < liczbaslow; i++ )
    {
        pustatablica[ i ] =( char * ) malloc( liczbaslow * sizeof( char ) );
        pustatablica[ i ] = 0;
    }
    return pustatablica;
}

void zwolnijpamiec( int liczbaslow, char ** tablicaslow ) //funkcja zwalniajaca pamiec
{
    int i;
    for( i = 0; i < liczbaslow; i++ )
    {
        free( tablicaslow[ i ] );
    }
    free( tablicaslow );
}

void sortowanie( int liczbaslow, char ** tablicaslow )
{
    int i;
    char m;
    for( i = 0; i < liczbaslow; i++ )
    {
        if( strcmp( tablicaslow[ i ], tablicaslow[ i + 1 ] ) < 0 )
        {
            m = tablicaslow[ i ];
            tablicaslow[ i + 1 ] = tablicaslow[ i ];
            tablicaslow[ i + 1 ] = m;
        }
    }
}

void wypisz( int liczbaslow, char ** tablicaslow )
{
    int i;
    for( i = 0; i < liczbaslow; i++ )
    {
        printf( "%s\n", tablicaslow[ i ] );
    }
}

void zapisdopliku( int liczbaslow, char ** tablicaslow )
{
    int i;
    FILE * fp;
    fp = fopen( "test1.txt", "w" );
    for( i = 0; i < liczbaslow; i++ )
    {
        fprintf( fp, "%s\n", tablicaslow[ i ] );
    }
}
P-133294
michal11
» 2015-06-07 22:16:32
1. kod w znaczniki
2. źle zwalniasz pamięć, w pętli powinieneś dodać indeks
3. również źle alokujesz, najpierw przypisujesz do wskaźnika utworzony obszar pamięci a później od razu go "zapominasz" nadpisując ten wskaźnik. Samo alokowanie tez jest złe, skoro nie wiesz jak długi jest słowo to jak chcesz zarezerwować dla niego pamięć ?
liczbaslow * sizeof( char )
 ten fragment jest bez sensu
4. dodatkowo w funkcji odczytzpliku znowu alokujesz pamięć co prowadzi do wycieku pamięci (tej wcześniej zaalokowanej)
5. w funkcji odczytzpliku najpierw powinieneś odczytać słowo z pliku, sprawdzić jego długoś (strlen) zaalokować pamięć i skopiować string (strcpy), ważne jest użycie funkcji a nie przypisania
6. w funkcji zapisdopliku znowu zapomniałeś o indeksie

Tak na poczatek
P-133304
ziomal123456789
Temat założony przez niniejszego użytkownika
» 2015-06-08 08:25:24
Czyli zamiast liczbaslow*sizeof(char) powinienem wrzucić liczbaslow*sizeof (dlugoscslowa)?
P-133310
michal11
» 2015-06-08 09:49:38
nie sizeof a strlen()+1
i nie mnożysz tego przez liczbę słów bo to jest bez sensu, liczba słów jest ci potrzebna tylko do zaalokowania długości tablicy
P-133311
ziomal123456789
Temat założony przez niniejszego użytkownika
» 2015-06-08 11:31:11
Czyli coś takiego tak? Wszystko działa poza odczytem z pliku.
C/C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int podaj_dane();
void uzupelnijplik( int liczbaslow );
char ** tworztabliceslow( int liczbaslow );
char ** odczytzpliku( int liczbaslow, char ** tablicaslow );
void zwolnijpamiec( int liczbaslow, char ** tablicaslow );
void sortowanie( int liczbaslow, char ** tablicaslow );
void wypisz( int liczbaslow, char ** tablicaslow );
void zapisdopliku( int liczbaslow, char ** tablicaslow );

int main()
{
    int liczbaslow, i, j;
    liczbaslow = podaj_dane();
    uzupelnijplik( liczbaslow );
    //char **pustatablica=tworztabliceslow(liczbaslow);
    //char **tablicaslow=odczytzpliku(liczbaslow,pustatablica);
    odczytzpliku( liczbaslow, tworztabliceslow( liczbaslow ) );
    zwolnijpamiec( liczbaslow, tworztabliceslow( liczbaslow ) );
}

void uzupelnijplik( int liczbaslow ) //funkcja uzupelniajaca plik slowami
{
    int i;
    char slowo[ 20 ];
    FILE * fp;
    printf( "Podaj wyrazy. Po kazdym wcisnij enter \n" );
    if(( fp = fopen( "test.txt", "w" ) ) == NULL )
    {
        printf( "Nie moge otworzyc pliku test.txt do zapisu!\n" );
        exit( 1 );
    }
    for( i = 0; i < liczbaslow; i++ )
    {
        scanf( "%s", slowo );
        fprintf( fp, "%s\n", slowo );
    }
    fclose( fp );
};

int podaj_dane() //funkcja pobierajaca dane od uzytkownika
{
    int liczbaslow;
    printf( "Podaj liczbe wyrazow \n" );
    scanf( "%i", & liczbaslow );
    return liczbaslow;
}

char ** odczytzpliku( int liczbaslow, char ** tablicaslow ) //funkcja odczytujaca slowa z pliku
{
    int i, dlugosc;
    FILE * fp, * fb;
    char slowo[ 20 ];
    fp = fopen( "test.txt", "r" );
    for( i = 0; i < liczbaslow; i++ )
    {
        fscanf( fp, "%s\n", slowo );
        tablicaslow[ i ] =( char * ) malloc( strlen( slowo ) + 1 );
        strcpy( slowo, tablicaslow[ i ] );
    }
    fclose( fp );
    return tablicaslow;
   
}

char ** tworztabliceslow( int liczbaslow ) //funkcja tworzy pustą tablicę słów
{
    int i;
    char ** pustatablica =( char ** ) malloc( liczbaslow * sizeof( char * ) );
    for( i = 0; i < liczbaslow; i++ )
    {
        pustatablica[ i ] = 0;
    }
    return pustatablica;
}

void zwolnijpamiec( int liczbaslow, char ** tablicaslow ) //funkcja zwalniajaca pamiec
{
    int i;
    for( i = 0; i < liczbaslow; i++ )
    {
        free( tablicaslow[ i ] );
    }
    free( tablicaslow );
}

void sortowanie( int liczbaslow, char ** tablicaslow )
{
    int i;
    char m;
    for( i = 0; i < liczbaslow; i++ )
    {
        if( strcmp( tablicaslow, tablicaslow[ i + 1 ] ) < 0 )
        {
            m = tablicaslow;
            tablicaslow[ i + 1 ] = tablicaslow;
            tablicaslow[ i + 1 ] = m;
        }
    }
}

void wypisz( int liczbaslow, char ** tablicaslow )
{
    int i;
    for( i = 0; i < liczbaslow; i++ )
    {
        printf( "%s\n", tablicaslow );
    }
}

void zapisdopliku( int liczbaslow, char ** tablicaslow )
{
    int i;
    FILE * fp;
    fp = fopen( "test1.txt", "w" );
    for( i = 0; i < liczbaslow; i++ )
    {
        fprintf( fp, "%s\n", tablicaslow[ i ] );
    }
}
P-133314
michal11
» 2015-06-08 12:22:57
odczytzpliku wygląda prawie dobrze, znowu zapomniałeś o indeksach tablicy. Reszta do poprawy. Wstawiaj kod w znaczniki !
P-133315
ziomal123456789
Temat założony przez niniejszego użytkownika
» 2015-06-08 13:40:26
Te indeksy gubią się przy jak kopiuję kod na forum. Prawie dobrze tzn. co jest jeszcze nie tak z tym odczytem? Bo kompilować się kompiluje, ale wyrzuca jakieś krzaki.
P-133318
Monika90
» 2015-06-08 13:50:22
indeksy nie będą się gubiły jeśli dasz kod pomiędzy [cpp] a [/cpp]
P-133319
« 1 » 2
  Strona 1 z 2 Następna strona