#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???
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:
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);
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.
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.
In check_database()
you return 1
but the function is declared as not returning anything. It should just be return
.
In check_database()
you should call clearBuffer()
after scanf("%i", &punya_akun)
.
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.
(Not fixed) Always check the return value from I/O functions like fgets()
, scanf()
etc.
(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