0

Jumlah means total in English. My problem here if I run this program and run case number 2 which one run for see the data content. But if I run this program like being skipped. like in this picture enter image description here

I already check all specifier format in scanf. But no one works. Oh content of file is already exist. in here I add the content use case 1.

This is my code:

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

// define book
#define MAX_TITLE_BOOK 75
#define MAX_AUTHOR 75
#define MAX_CATEGORY 75
#define MAX_SIZE_BOOK 75
//define book

//define data
#define MAX_NAME_STUDENTS 25
//define data

//struct
typedef struct
{
    char titleBook[MAX_TITLE_BOOK];
    char authorBook[MAX_AUTHOR];
    char categoryBook[MAX_CATEGORY];
    int codeBook;
}Book;

typedef struct 
{
    char name[MAX_NAME_STUDENTS];
    int id;
    int codeBook;
    int dateBorrow[3]; 
    int dateReturn[3];
}Borrow;

//struct


void add(Book x[],int total){         // add (1)
    for(int i = 0; i < total; i++){
        fflush(stdin);
        printf("Masukan Judul Buku ke-%d: ", i + 1);
        scanf("%[^\n]s", x[i].titleBook);
        fflush(stdin);
        printf("Masukan Penulis Buku: ");
        scanf("%[^\n]s", x[i].authorBook);
        fflush(stdin);
        printf("Masukan Kategori Buku: ");
        scanf("%[^\n]s", x[i].categoryBook);
        fflush(stdin);
        printf("Masukan Kode Buku: ");
        scanf("%d", &x[i].codeBook);
    }
}

void see_data(Book* x, int* total) {
    FILE* file = fopen("data-book.txt", "a");
    if (file == NULL) {
        printf("No data found!!\n");
        return;
    }
    *total = 0;
    while(fscanf(file, "%s, %s, %s, %d", x[*total].titleBook, x[*total].authorBook, x[*total].categoryBook, &x[*total].codeBook) == 4) {
      (*total)++;  
    }
    fclose(file);
}

void output_see(Book x[], int y){
    for(int i = 0; i < y; i++){
        printf("Nomor: %d\n", i+1);
        printf("Title: %s\n", x[i].titleBook);
        printf("Author: %s\n", x[i].authorBook);
        printf("Category: %s\n", x[i].categoryBook);
        printf("Code: %d\n", x[i].codeBook);
    }
}



void save(Book* x, int total){ // save(3) = save data yang diinput kedalam data-book.txt
    FILE* file = fopen("data-book.txt", "a");
    if(file == NULL){
        printf("Can not see the contents of the data");
    }

    for(int i = 0; i < total; i++){
        fprintf(file, "%s, %s, %s, %d\n", x[i].titleBook, x[i].authorBook, x[i].categoryBook, x[i].codeBook);
    }
    fclose(file);
    printf("\nData saved successfully to database");

}

void change(Book x[], int y){
    int index_data;
    fflush(stdin);
    printf("Enter the data number you want to change: ");
    scanf("%d", &index_data);
    fflush(stdin);

    // ganti data
    printf("Masukan Judul baru:");
    scanf("%[^\n]s", x[index_data - 1].titleBook);
    fflush(stdin);
    printf("Masukan Author buku baru:");
    scanf("%[^\n]s", x[index_data - 1].authorBook);
    fflush(stdin);
    printf("Masukan Category buku baru:");
    scanf("%[^\n]s", x[index_data - 1].categoryBook);
    fflush(stdin);
    printf("Masukan Kode buku baru:");
    scanf("%d", &x[index_data - 1].codeBook);
    fflush(stdin);
}




int main (){
    //declare
    char password[25] = "admin", username[25] = "admin";
    char checkPass[25], checkUser[25], back_menu, contentFile[100];
    Book data[100];
    FILE* file;
    int menu_program, jumlah, limit = 0;
    //declare

    do{
        printf("Input Username: ");
        scanf("%s", checkUser);
        printf("\nInput Password: ");
        scanf("%s", checkPass);
        if(strcmp(checkUser, username) == 0 && strcmp(checkPass, password) == 0){
            printf("\tSuccessful Login!\n");
            break;
        }else{
            printf("Password or Username wrong!\n");
        }
        limit++;
    }while(limit < 3);
    
    if(limit > 3){
        printf("\nToo many request, please try again in 30 sec!");
    }

    do{
        if(limit < 3){
            printf("\n\t================================================");
            printf("\n\tLibrary System Institut Teknologi Telkom Surabaya");
            printf("\n\t================================================");
            printf("\n\t1. Add Data");
            printf("\n\t2. Read Data");
            printf("\n\t3. Change/Update Data");
            printf("\n\t4. Search Data");
            printf("\n\t5. Sort Data");
            printf("\n\t6. Book Borrow");
            printf("\n\t7. Return Book");
            printf("\n\t0. Exit");
            printf("\n\tInput Menu: ");
            scanf("%d", &menu_program);
               }

            switch (menu_program){
            case 1:
                printf("\nHow many books will be input: ");
                scanf("%d", &jumlah);
                fflush(stdin);
                add(data, jumlah);
                save(data, jumlah);
            break;
            case 2:
                see_data(data, &jumlah);
                output_see(data, jumlah);
                break;
            case 3:
                file = fopen("data-book.txt", "w");
                change(data, jumlah);
                    // simpen data
                    if(file == NULL){
                        printf("Failed to open file!");
                    }
                    for(int i = 0; i < jumlah; i++){
                        fprintf(file, "%s, %s, %s, %d\n", data[i].titleBook, data[i].authorBook, data[i].categoryBook, data[i].codeBook);
                    }
                    fclose(file);
                break;
            default:
                break;
            }
        }while(menu_program != 0);
    return 0;
}

I expect in terminal will show content of data (data-book.txt)

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
  • 1
    I removed the C++ tag, this is a pure "C" question (C++ is a different language, with some "C" backward compatibility). – Pepijn Kramer Jan 19 '23 at 12:59
  • I alrd change format for read data use "a", but the result is the same – Newbie Programmer Jan 19 '23 at 12:59
  • 1
    ```fflush(stdin)``` is undefined behaviour... – Harith Jan 19 '23 at 13:00
  • `"%[^\n]s"` is a "beginner's hybrid" of the two quite different format specs `"%s"` and `%[]`. The `%[]` isn't a variant of `%s` and `scanf` will attempt to match the `"s"` with the next input. Instead of `scanf("%[^\n]s", x[i].titleBook);` use `scanf(" %[^\n]", x[i].titleBook);` note the added space too. – Weather Vane Jan 19 '23 at 13:00
  • is there any other way besides using ```fflush(stdin);```? – Newbie Programmer Jan 19 '23 at 13:01
  • Why use ```scanf``` and family when you're going to ignore what they return?.. – Harith Jan 19 '23 at 13:01
  • 2
    Use `fgets()` to read a line of input, then use `sscanf()` to parse it. – Barmar Jan 19 '23 at 13:03
  • The `scanf` (and family) format `%s,` will not work if there's no space between the string and the comma. The `%s` specifier reads **space** delimited strings. So an input like `foo, ...` will be read as a four character word and include the comma. – Some programmer dude Jan 19 '23 at 13:04
  • @NewbieProgrammer *is there any other way?* Yes: Don't use `scanf`. It's good for a few simple things, but for anything complicated you often find yourself needing to use `fflush(stdin)`, but `fflush(stdin)` is terrible and basically doesn't work. See also [this answer](https://stackoverflow.com/questions/2979209/using-fflushstdin/58884121#58884121). See [here](https://stackoverflow.com/questions/58403537) for `scanf` alternatives. – Steve Summit Jan 19 '23 at 13:12
  • Please do not show pictures of text. Instead copy&paste your text directly into the question. That applies to your code, error messages during compilation and also to the output of your program. – Gerhardh Jan 19 '23 at 14:06
  • `scanf("%[^\n]s", x[index_data - 1].authorBook);` is going to stop scanning at the newline left in the buffer by the previous `scanf("%[^\n]s", x[index_data - 1].titleBook);` because `fflush(stdin)` is incorrect. As well as having an incorrect `s` in the format. Do yourself a favour: ***always*** check that the correct number of items was converted. – Weather Vane Jan 19 '23 at 16:12

1 Answers1

0

You open the file with mode a (append mode). This will not allow you to read the file content.

Please check the available modes in the documentation (e.g., here). For only reading the file content, you might want to use r (or any of the ones with the +, depending on your use case).

If this doesn't work (actually, do this in any case), you should spend some effort to build error handling into your app, e.g., by detecting if calls fail and using errno for diagnosis (example).

moooeeeep
  • 31,622
  • 22
  • 98
  • 187