There's a problem when im inputting username to store to a file but it won't store

71 Views Asked by At
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

void tampilan_awal()
{
    int angka_daerah;
    do {
    printf("Daerah\n.....................................\n1. Daerah\n");
    printf("Ketik angka 1 jika ingin memilih daerah yang dituju dan angka 0 jika tidak ingin melanjutkan!\n"); //Click 1 if you wanna choose destination(daerah) you wanna go and click 0 if you don't want to continue
    scanf("%i", &angka_daerah);
    if(angka_daerah == 1)
    {
        pilihdaerahutama();
    } else if(angka_daerah == 0)
    {
        break;
    }
    } while (angka_daerah != 1 && angka_daerah != 0);
}

void daftar_akun_database() {
    FILE *filePointer;
    char username[30];
    char password[30];

    // Buka file untuk menulis
    filePointer = fopen("`touch filename.txt`", "a");

    printf("Buat username dan password\n");

    printf("Username: ");
    fgets(username, sizeof(username), stdin);
    clearBuffer();

    printf("Password: ");
    fgets(password, sizeof(password), stdin);
    clearBuffer();

    // Menghapus karakter newline dari username dan password
    strtok(username, "\n");
    strtok(password, "\n");

    fprintf(filePointer, "Username: %s\nPassword: %s\n", username, password);

    fclose(filePointer);

    filePointer = fopen("filename.txt", "r");
    fseek(filePointer, 0, SEEK_SET);

    check_database();
}


void clearBuffer() {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

void check_database() {
    FILE *filePointer;
    char username[50];
    char line[50];
    char password[50];
    bool found = false;
    int punya_akun;

    // Buka file untuk membaca
    filePointer = fopen("filename.txt", "r");

    // Periksa keberhasilan pembukaan file
    if (filePointer == NULL) {
        printf("Gagal membuka file.\n");
        return 1;
    }

    // Meminta pengguna untuk memasukkan username dan password
    printf("Masukkan username dan password\n");
    printf("Masukkan username: ");
    fgets(username, sizeof(username), stdin);
    clearBuffer();
    strtok(username, "\n"); // Menghapus newline

    printf("Masukkan password: ");
    fgets(password, sizeof(password), stdin);
    clearBuffer();
    strtok(password, "\n"); // Menghapus newline

    // Loop untuk membaca setiap baris dari file
        while (fgets(line, sizeof(line), filePointer) != NULL) {
        // Menghapus karakter newline dari setiap baris
            strtok(line, "\n");

        // Memeriksa apakah username dan password ada dalam baris
            if (strstr(line, "Username: ") != NULL && strstr(line, username) != NULL &&
                fgets(line, sizeof(line), filePointer) != NULL && // Membaca baris Password
                strstr(line, "Password: ") != NULL && strstr(line, password) != NULL) {
                printf("Username dan password benar!\n");
                found = true;
                tampilan_awal();

        }
    }
    if(!found)
    {
        printf("Username tidak dapat ditemukan silahkan coba lagi.\n");
        do{
        printf("Sudah punya akun? Silahkan ketik 1 untuk daftar dan 2 untuk coba lagi: ");
        scanf("%i", &punya_akun);
        if(punya_akun == 1)
        {
            daftar_akun_database();
        } else{
            check_database();
        }
        } while(punya_akun != 1 && punya_akun != 2);
    }
  

    fclose(filePointer);

}

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

i don't know what's wrong with my code :(, the lecturer didn't teaching the f gets and gets function properly, they do it in such a rush. They recommend me using gets, while i just know f gets because i study at w3schools. Can someone give me the correct code and which area i did wrong?? im so clueless and the deadline is tomorrow(we have to presented it online)

i tried input the username and password but on the file there's no username at all. just like this Username: Password: 1234

i think this has something to do with the fgets and the function clearBuffer but i have no idea where is exactly wrong. The function clearBuffer just made some new space like if we go to the check_database function it showed like this Username: 1234 (enter) (enter) Password: 5678 (enter) (enter)

I do not understand what is happening, can someone explain this to me???

1

There are 1 best solutions below

4
Allan Wind On BEST ANSWER

In check_database() you read a line with fgets() which consumes the trailing \n. Then you call clearBuffer() which will block in getchar() till the stream is closed with Ctrl-D to generate the EOF as there is no \n left in the stream. Simply don't call clearBuffer() after reading a line with fgets().

Here are some other issues:

  1. strtok(username, "\n") is a slightly strange way to strip the trailing newline of a non-empty line ("...\n") and it doesn't strip it from an empty line ("\n"). Consider using this instead:

    #define strip(s) (s)[strcspn((s), "\n")]='\0'
    // ..
    strip(username);
    
  2. If user is not found in the database (as it starts out empty) you provide the option to write it. You should close the file before calling daftar_akun_database(), or even better open the file in main() and pass it to the functions that need access to it.

  3. In main() you call check_database() from main() but then loop forever in the bottom by calling check_database() recursively. Eventually it will run of stack space. It's better to call daftar_akun_database() if you need to and then return and have the loop in main() instead. It's also odd that you call check_database() from daftar_akun_database() so don't do that.

  4. In check_database() you return 1 but the function is declared as not returning anything. It should just be return.

  5. In check_database() you should call clearBuffer() after scanf("%i", &punya_akun).

  6. If the user is not found, I think, option 1 is meant to write it. You should pass the username and password to daftar_akun_database() instead of asking the user for the same information again.

  7. (Not fixed) Always check the return value from I/O functions like fgets(), scanf() etc.

  8. (Not fixed) Use symbolic constants instead of magic values (50). It's not a big deal in your program as you usesizeof when calling fgets().

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

#define PATH "filename.txt"
#define strip(s) (s)[strcspn((s), "\n")]='\0'

void check_database(FILE *database);
void clearBuffer(void);
void daftar_akun_database(FILE *database, const char *usernmame, const char *password);
void tampilan_awal();

void check_database(FILE *database) {
    char username[50];
    char line[50];
    char password[50];
    bool found = false;
    int punya_akun;

    // Meminta pengguna untuk memasukkan username dan password
    printf("Masukkan username dan password\n");
    printf("Masukkan username: ");
    fgets(username, sizeof(username), stdin);
    strip(username);

    printf("Masukkan password: ");
    fgets(password, sizeof(password), stdin);
    strip(password);

    // Loop untuk membaca setiap baris dari file
    rewind(database);
    while (fgets(line, sizeof(line), database) != NULL) {
        strip(line);
        // Memeriksa apakah username dan password ada dalam baris
        if (strstr(line, "Username: ") != NULL && strstr(line, username) != NULL &&
            fgets(line, sizeof(line), database) != NULL && // Membaca baris Password
            strstr(line, "Password: ") != NULL && strstr(line, password) != NULL) {
            printf("Username dan password benar!\n");
            found = true;
            tampilan_awal();

        }
    }
    if(!found) {
        printf("Username tidak dapat ditemukan silahkan coba lagi.\n");
        for(;;) {
            printf("Sudah punya akun? Silahkan ketik 1 untuk daftar dan 2 untuk coba lagi: ");
            scanf("%i", &punya_akun);
            clearBuffer();
            if(punya_akun == 1) {
                daftar_akun_database(database, username, password);
                break;
            } else if(punya_akun == 2)
                break;
        }
    }
}

void clearBuffer(void) {
    int c;
    while ((c = getchar()) != '\n' && c != EOF);
}

void daftar_akun_database(FILE *database, const char *username, const char *password) {
    fseek(database, 0, SEEK_END);
    fprintf(database, "Username: %s\nPassword: %s\n", username, password);
}


// implementation was not provided initially
void tampilan_awal() {}

int main() {
    FILE *database = fopen(PATH, "a+");
    if(!database) {
        printf("Gagal membuka file.\n");
        return 1;
    }
    for(;;)
        check_database(database);
    return 0;
}

and example session:

$ rm filename.txt
$ ./a.out
Masukkan username dan password
Masukkan username: bob 
Masukkan password: pass
Username tidak dapat ditemukan silahkan coba lagi.
Sudah punya akun? Silahkan ketik 1 untuk daftar dan 2 untuk coba lagi: 1
Masukkan username dan password
Masukkan username: bob2
Masukkan password: pass
Username tidak dapat ditemukan silahkan coba lagi.
Sudah punya akun? Silahkan ketik 1 untuk daftar dan 2 untuk coba lagi: 2
Masukkan username dan password
Masukkan username: bob 
Masukkan password: pass
Username dan password benar!
Masukkan username dan password