Pobieranie zmiennej

0

Cześc, problem jest następujący. Dlaczego pierwszy program dziala a drugi wywala crasha? Jaka jest różnica miedzy jednym a drugim kodem? jak to zrobic lepiej?

#include <stdio.h>
int main(){
    char* haslo[1];
    printf("Wprowadź haslo aby uzyskac dostep do aplikacji: ");
    gets(haslo);
    printf("haslo: %s ",haslo);
    getch();
    return 0;
}
#include <stdio.h>
int main(){
    char* haslo;
    printf("Wprowadź haslo aby uzyskac dostep do aplikacji: ");
    gets(haslo);
    printf("haslo: %s ",haslo);
    getch();
    return 0;
}
0

A czy hasło nie ma czasem więcej niż jeden znak? Zobacz korzystasz z typu który przetrzymuje znak. W pierwszym wypadku korzystasz z tablicy a w drugim nie.

4

Oba programy są niepoprawne. Do gets (swoją drogą użycie tej funkcji jest niezalecane, a z nowszych standardów została ona kompletnie usunięta) podajesz wskaźnik na bufor.

Pierwszy Ci "działa" ponieważ deklarujesz tablicę 1 wskaźników na char, a wskaźnik ma na popularnych systemach 4 lub 8 bajtów wielkości, co pozwala bezpiecznie trzymać odpowiednio 3 i 7 znaków hasła.

Użyj malloc do zaalokowania odpowiednio dużej przestrzeni lub zdefiniuj tablicę charów: char buf[32]; // max 31 znakow hasla

0

Czy teraz aplikacja jest napisana poprawnie?

#include <stdio.h>
int main(){
     char buf[32];
    printf("Wprowadź haslo aby uzyskac dostep do aplikacji: ");
    scanf("%s",buf);
    printf("haslo: %s ",buf);
    getch();
    return 0;
}

1

Wygląda ok¹, ale opisy są mylące, bo hasła nigdzie nie weryfikujesz ;)

¹ nie jest w pełni poprawnie, tak jak @pingwindyktator i @kaczus zauważyli, ale biorąc pod uwagę dział uważam że jest to akceptowalne.

0

Nie mogłem go zweryfikować bo na dzień dobry pojawił się problem z jego pobraniem. Dzieki za pomoc, temat niech zostanie do wieczora otwarty - moze sie przydać.

2

Nie jest okej bo jak ktoś wprowadzi przez scanf bardzodlugibufnapewnodluzszyniztrzydziescidwaznaki to masz buffer overflow.

0

@up

Jaka rada?Dodam ze jak dam buf nie 32 tylko np. 2 to i tak moge sobie "takiedlugiehaslo" wprowadzic i mi je wyswietli.

//edit
Jednak nie moge.

1

Albo wczytujesz z ograniczeniem długości, albo godzisz się na UB (undefined behavior) jeśli wpisane dane są za długie.

http://en.cppreference.com/w/c/io/fscanf

Np. dla char buf[32] możesz zapisać scanf("%31s", buf) (zwróć uwagę, że limit jest 31 dla scanf, ponieważ na końcu musi być miejsce dla znaku zerowego)

2

Nie jest idealne, ale możesz

scanf("%31s",buf);

wtedy jak ktoś wprowadzi bardzo długie hasło (dłuższe niż powinien), to obetniesz do pierwszych 31 znaków.

Dodam ze jak dam buf nie 32 tylko np. 2 to i tak moge sobie "takiedlugiehaslo" wprowadzic i mi je wyswietli.
Tak, tyle że to minus a nie plus. Bo nie zdajesz sobie sprawy z tego, że to jest błąd. Raz zadziała, raz nie. Już lepiej żeby zawsze program się wywalił.

0
twonek napisał(a):

Nie jest idealne, ale możesz

scanf("%31s",buf);

wtedy jak ktoś wprowadzi bardzo długie hasło (dłuższe niż powinien), to obetniesz do pierwszych 31 znaków.

Dodam ze jak dam buf nie 32 tylko np. 2 to i tak moge sobie "takiedlugiehaslo" wprowadzic i mi je wyswietli.
Tak, tyle że to minus a nie plus. Bo nie zdajesz sobie sprawy z tego, że to jest błąd. Raz zadziała, raz nie. Już lepiej żeby zawsze program się wywalił.

Nie obcina znakow, dalej moge wpisac ich wiecej. Jesli jest ich za duzo to wywala program.

0

@up
Dziala, %31s wyladowalo w printf a nie w scanfie ;) Dzieki

2

Zawsze można użyć realokacji pamięci:

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

char *readline()
{
    int length = 8;
    char *buffer = (char*)malloc(length * sizeof(char));

    int character = 0;
    int count = 0;
    while((character = getchar()) != '\n' && character != EOF)
    {
        if(count == length)
        {
            char *temp = (char*)realloc(buffer, (length += count) * sizeof(char));
            if(temp) buffer = temp;
            else
            {
                free(buffer);
                buffer = NULL;
                return buffer;
            }
        }
        buffer[count] = character;
        count += 1;
    }

    buffer[count] = '\0';
    return buffer;
}

int main(){
    printf("Enter password: ");

    char *password = readline();
    if(password)
    {
        printf("Your password: %s", password);
        free(password);
    }

    return 0;
}
0
piopat napisał(a):

@up
Dziala, %31s wyladowalo w printf a nie w scanfie ;) Dzieki

Co?

0

Pracowalem caly czas przy PHP, i na logike ten program powinien mi dzialac... nie dziala w ogole. caly czas wykonuje funkcje get_pass. Jakieś rady?

#include <stdio.h>

 char buf[20];
 char pass[20]="pat";

int main(){
     get_pass();
    return 0;
}


int get_pass(){

    printf("Wprowadź haslo aby uzyskac dostep do aplikacji:\nHASLO:\n");
    scanf("%19s",buf);
    if(buf==pass)
    {
        aplikacja();
    }else{
        printf("Haslo %s jest niepoprawne!\nPoprawne haslo to %s\n",buf,pass);
        get_pass();
    }


return 1;
}

int aplikacja(){

puts("To jest program");

return 1;
}
3

strcmp(buf, pass)

5

W C dla ułatwienia porównanie stringów robi się używając funkcji strcmp lub strncmp. Inaczej porównujesz wskaźniki. http://en.cppreference.com/w/c/string/byte/strncmp

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