简体   繁体   中英

C phone book program: how to exit avoid infinite loop and how to return to the switch statement menu

I have a simple phone book written in C that saves input info to a text file on my pc.

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

void validateName(char name[], FILE *fptr);
void validateID(char id[], FILE *fptr);
void validateScore(int score, FILE *fptr);
void addContact(char name[], char id[], int score, FILE *fptr);
void printContact(FILE *fptr);
void printAll();

int main()
{
    char name[30], id[10];
    int score;
    int i;

   FILE *fptr;
   fptr = fopen("C:\\c\\program.txt","w");

   if(fptr == NULL)
   {
      printf("Error!");   
      exit(1);             
   }
    else {  

        bool flag = true;
        do{
            printf("\n1. Press 1 to display record\n"
                   "2. Press 0 to add a new contact\n"
                   "3. Press -1 to display all records\n\n");

            int option;
            scanf("%d", &option);
            switch(option) {
                case 1:
                    printContact(fptr);
                    flag = false;
                    break;
                case 0:
                    addContact(name, id, score, fptr);
                    flag = false;
                    break;
                case -1:
                    printAll();
                    flag = false;
                    break;
                default:
                    printf("wrong choice, try again\n\n");             
            }       

        } while(flag);  

    fclose(fptr);
    return(0);
    }   
}

void validateName(char name[], FILE *fptr){

    bool flag = true;

    while(flag){
        fgets(name, 30, stdin);
        if ((strlen(name) < 3) || (strlen(name) > 20)) {
                printf("error\nplease enter name again: ");
        } else {
            flag = false;
        }       
    }   
}

void validateID(char id[], FILE *fptr){

    bool flag = true;
    while(flag) {
         if (!isalpha(id[0])){
            printf("enter a letter as first char\n");  
        }
         else if(strlen(id) > 10) {
            printf("error too much numbers \n");
        } else {
             flag = false;
         }
    }
}

void validateScore(int score, FILE *fptr) {

        if(score >= 0 && score <= 100) {
            fprintf(fptr, "SCORE: %d\n", score);
            } else {
                printf("invalid input");

                (exit(1));
            }
}

void addContact(char name[], char id[], int score, FILE *fptr) {

    //first name 
    printf("Enter name: ");    
    scanf("%s", name);
    validateName(name, fptr);
    fprintf(fptr,"NAME: %s \n", name);  

     //id   
    printf("Enter id: ");
    scanf("%s", id);
    validateID(id, fptr);
    fprintf(fptr,"STUDENT NO: %s\n", id);

    //score      
    printf("enter score: ");
    scanf("%d", &score);
    validateScore(score, fptr);
}

void printContact(FILE *fptr) {

    int c;
    char contacts[50];

   while((c = getchar()) != EOF) {
       fscanf(fptr, "%s", &contacts);

       for(int i = 50; i < 50; i++){
           printf("%s", &contacts);
       }
   }




}

void printAll() {

}

my first issue is within the validateID function: I keep getting into an infinite loop when I try to validate the first condition, which is to make sure the first index is a character.

My second issue is, when the I enter name, student id and score, the program finishes and I don't return to the menu switch statement to select other options?

What am I doing wrong or what am I missing?

The idea of having functions like void validateXXX is in my opinion wrong. Compare it to isalpha which is similar to a validation. isalpha returns an int so that you can use it for checking. Your validation functions should probably do the same. So instead of:

void validateID(char id[], FILE *fptr){

    bool flag = true;
    while(flag) {
         if (!isalpha(id[0])){
            printf("enter a letter as first char\n");  
        }
         else if(strlen(id) > 10) {
            printf("error too much numbers \n");
        } else {
             flag = false;
         }
    }
}

the function could be:

int validateID(char id[]){
    if (!isalpha(id[0])){
            printf("enter a letter as first char\n");  
            return 0;
    }    
    if(strlen(id) > 10) {
            printf("error too much numbers \n");
            return 0;
    }    
    return 1;
}

and then you could use it like:

do {
    scanf("%s", id);    // See below !!!!
} while(!validateID(id));

so that you keep reading until a valid ID has been entered.

Next:

Never use scanf("%s", ...) - Never

There is no check for the length of the input so the user can input some text being too long to be stored in the buffer you provide (eg id ). That will be catastrophic for your program as it would write outside array boundary. Your program may crash or do all sorts of strange things.

You should use fgets for reading user input. It is much easier and much more secure.

For your main-loop:

Yes, of cause it will terminate as you set flag to false in all case s in the switch .

For validateID() , you aren't changing anything within the while loop that would cause termination. You're always checking id[0] or strlen(id) , but not changing anything about id or how you're checking it. If id[0] isn't alphanumeric, you'll just loop on that forever. Or, if it is alphanumeric but strlen(id) is <= 10, you'll loop on that forever. What exactly are you looping on here?

Your program terminates after a single menu selection because all selections set flag to false and it's never re-initialized to true - so the while loop terminates and your program ends.

Following is the declaration for isalpha() function.

int isalpha(int c);

This function returns a non-zero value if c is an alphabet, else it returns 0. Your while will always have a true condition maintained. its entering one of the two cases above right? So once it leaves, make sure you return false or 0 to the while so that it comes out. Now it is up to you how u modify this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM