Zabezpieczenie programu przed wprowadzeniem zbyt duzej liczby znakow - pomoc

0

Witam,

Mam program, który (jak wyrzuca mi maszyna sprawdzająca kod) nie jest zabezpieczony przed wprowadzeniem zbyt duzej liczby znakow.
Dokładny błąd zamieszczam w komentarzu na samej górze kodu w linku z gdbonline ale nieznacznie się różni od tego w temacie.
https://onlinegdb.com/HyuvDdzzN
Niestety nie wiem w którym miejscu leży błąd. Prawdopodobnie jakiś scanf jest przyczyną ale dodałem ograniczenia "%50c" itd.

opis zadania: losowe wartosci wrzucam w strukture, pokazuje jakie zostaly wylosowane. Nastepnie pytam czy wrzucic je do pliku. Jak uzytkownik sie zgodzi to wczytuje dane do pliku i zapisuje plik. Moze to byc plik z rozszerzeniem txt lub bin - wybiera uzytkownik wpisujac sciezke do pliku z rozszerzeniem .txt / .bin
W sciezke do pliku mozna wpisac po prostu: dane.txt (plik sie zapisze tam gdzie jest program)

Kod programu:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
struct point_t
{
    int x;
    int y;
} s1, s2;

struct point_t* set(struct point_t* p, int x, int y); //przekazanie wartosci x i y do obiektu struktury
void show(const struct point_t* p); //wypisanie danych ze struktury

int save_point_b(const char *filename, const struct point_t* p);
int load_point_b(const char *filename, struct point_t* p);
int save_point_t(const char *filename, const struct point_t* p);
int load_point_t(const char *filename, struct point_t* p);
float distance(const struct point_t* p1,
               const struct point_t* p2, int *err_code);

int main()
{

    struct point_t *s2_p=&s2;
    int x=0;
    int y=0;

    //losowanie
    srand (time(NULL));
    x = (rand  () %20) ;
    y = (rand () %20);
    set(s2_p, x, y); //przypisuje wylosowane wartosci x i y, do wartosci x i y ze struktury dla obiektu s2
    show (s2_p); //wypisanie wartosci x i y ze struktury dla obiektu s2
    //podanie sciezki pliku
    char fileExt[100];
    char *fileExt_p=fileExt;
    printf("Podaj sciezke do pliku: ");
    scanf(" %50s", fileExt_p);

    //do sprawdzenia czy wpisane rozszerzenie pliku jest zgodne z .txt lub .bin
    fileExt_p+=strlen(fileExt)-4; //ustawienie wskaznika na poczatek
    char end[5]; 
    char * end_p=end;
    //dla binarnych i tekstowych
    char bin[]=".bin";
    char txt[]=".txt";

    char znak;
    int i ;
    for ( i = 0 ; i < 4 ; i ++ )
    {
        *end_p=*fileExt_p; //kopiowanie
        end_p++;
        fileExt_p++;
    }
    *end_p='\0'; 
    fileExt_p-=strlen(fileExt); //na poczatek
    if(isalpha(*fileExt_p)==0) //jesli nazwa pliku to liczba = blad
    {
        printf ("couldn't create file");
        return 1;
    }

    if (strcmp(end,bin) == 0) //gdy rozszerzenie bin (end i bin sa takie same wiec rozszerzenie bin)
    {
        if(save_point_b(fileExt,s2_p)==1) //jesli udalo sie zapisac
        {// i zapytaæ u¿ytkownika, czy chce odczytaæ dane z pliku.

            printf("File saved\n czy chcesz wczytac plik? Y/N\n");

            scanf(" %1c", &znak);
            //Po wpisaniu przez u¿ytkownika litery ‘Y’ lub ‘y’ program powinien odczytaæ dane z pliku o tej samej nazwie i wyœwietliæ je na ekranie.
            if ( znak == 'y' || znak == 'Y' )
            {
                if(load_point_b(fileExt,s2_p)==0) //gdy nie udalo sie odczytac danych z pliku
               {
                   printf ("File corrupted");
                   return 1;
               }
               else //jesli sie udalo, to wypisuje dane
                   show(s2_p);

            }
            else if ( znak == 'n' || znak == 'N')
                return 0;

            else
            {
                printf ("Error");
                return 1;
            }
        }
    }
    else if ( strcmp(end,txt)==0) //gdy rozszerzenie txt (end i txt sa takie same wiec rozszerzenie txt)
    {
        if( save_point_t(fileExt,s2_p) == 1 )
        {
        // i zapytac uzytkownika czy chce odczytac dane z pliku

            printf("File saved\nczy chcesz wczytac plik? Y/N\n");
            scanf(" %1c", &znak);
          //    printf("load point: %d\n",load_point_t(fileExt,s2_p));
            if ( znak == 'y' || znak == 'Y' )
            {
               if(load_point_t(fileExt,s2_p)==0)
               {
                   printf ("File corrupted");
                   return 1 ;
               }
               else
                   show(s2_p);
            }
            else if ( znak == 'n' || znak == 'N')

                return 0;
            else
            {
                printf ("Error");
               // 
                return 1;
            }
        }
    }
    else
    {
        printf ("Wrong filename!");
        return 1;
    }
    return 0;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void show(const struct point_t* p) //wypisanie danych
{
    if ( p!= NULL )
        printf("x = %d;  y = %d \n",p->x, p->y);
}

struct point_t* set(struct point_t* p, int x, int y) //przekazanie wartosci x i y do struktury
{
    if (p == NULL)
        return NULL;
    p->x=x;
    p->y=y;

    return p;
}
int save_point_b(const char *filename, const struct point_t* p) //zapis do pliku bin
{
    if ( p == NULL ||  filename == NULL)
        return 0;
    FILE * f =fopen(filename, "wb");
    if ( f == NULL)
        return 0;

    fwrite(&(p->x),4,1,f);
    fwrite(&(p->y),4,1,f);
    fclose(f);

    return 1;
}
int load_point_b(const char *filename, struct point_t* p) //odczyt z pliku bin
{
    if ( filename==NULL || p==NULL )
        return 0;

    FILE * f = fopen(filename,"rb");
    if ( f == NULL)
        return 0;

    if(fread(&(p->x),1,4,f)==0)
    {
        fclose(f);
        return 0;
    }
    if(fread(&(p->y),1,4,f)==0)
    {
        fclose(f);
        return 0;
    }
    fclose(f);

    return 1;

}
int save_point_t(const char *filename, const struct point_t* p) //zapis do pliku txt
{
    if ( p == NULL ||  filename == NULL)
        return 0;
    FILE * f = fopen( filename, "w");
    if (f==NULL)
         return 0;

    fprintf(f,"%d ",p->x);
    fprintf(f,"%d",p->y);
    fclose(f);

    return 1;

}
int load_point_t(const char *filename, struct point_t* p) //odczyt z pliku txt
{
     if ( filename ==  NULL || p == NULL )
        return 0;

    FILE * f= fopen(filename,"r");
    if ( f == NULL)
        return 0;

    char sin[100];
    char*znak=sin;
    fscanf(f,"%s", znak);
    p->x=atoi(znak);
    fscanf(f,"%s",znak);
    p->y=atoi(znak);
    fclose(f);
    return 1;
}

float distance(const struct point_t* p1,const struct point_t* p2, int *err_code) //funkcja distance z poprzednich zadan na odleglosc euklidesa
{
    if ( p1 == NULL || p2==NULL  )
    {
        if (err_code !=NULL)
        *err_code=1;
        return -1;
    }
    float distance_p = sqrt( pow (( p2->x-p1->x),2)+ pow (( p2->y-p1->y),2));
    if (err_code != NULL)
    *err_code=0;
    return distance_p;
}

Mógłby ktoś przejrzeć kod i powiedzieć co poprawić / usprawnić i co najważniejsze jak pozbyć się tego błędu?
Nagradzam lajkami i ptaszkiem! :D

0

Odświeżam.
Ktoś ma pomysł?

0

Nie obsługujesz błędów przy scanf(). Gdy wprowadzisz EOF (ctrl+z lub ctrl+d) zamiast wpisać cokolwiek to dostaniesz śmieci.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0