2017-02-17 197 views
0

我有一个简单的C语言电话簿,它将输入信息保存到我的电脑上的文本文件中。C电话簿程序:如何退出避免无限循环以及如何返回到switch语句菜单

#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() { 

} 

我的第一个问题是validateID函数中: 我一直陷入无限循环,当我尝试验证的首要条件,这是确保第一个索引是一个字符。

我的第二个问题是,当我输入姓名,学号和分数时,程序结束,我不回到菜单切换语句以选择其他选项?

我在做什么错,或者我错过了什么?

回答

0

对于validateID(),您不会更改会导致终止的while循环内的任何内容。你总是检查id[0]strlen(id),但不会改变任何关于id或你如何检查它。如果id[0]不是字母数字,您将永远循环。或者,如果它是字母数字,但是strlen(id)是< = 10,您将永远循环。你究竟在这里循环着什么?一个菜单选择后

你的程序终止,因为所有选项设置flag为false,它永远不会重新初始化true - 这样的while循环终止和你的程序结束。

+0

我和循环如果第一个字符非字母,如果有以下的第一个字母小于9个的数字。所以如果这些条件不满足,循环应该显示一个错误,并要求用户重新输入一个字母或重新输入一个有效的数字 – Rgoat

+0

我将如何重新初始化switch语句中的标志? – Rgoat

+0

你需要告诉计算机做你想做的事情。你的设计不适合做你想做的事情 - 我已经指出了你的程序为什么不起作用,作为编程人员来决定如何解决这个问题是由你来决定的,因为它是一个设计问题,反对一个特定的bug。 – Caleb

0

你有这条线printf("enter a letter as first char\n");

2

具有类似于void validateXXX功能的想法在我看来错后使用scanf。将其与isalpha进行比较,这与验证类似。 isalpha返回int,以便您可以使用它进行检查。你的验证功能应该可以做同样的事情。因此,而不是:

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; 
     } 
    } 
} 

的功能可能是:

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; 
} 

,然后你可以使用它像:

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

,让您随时阅读,直到已输入一个有效的ID 。

下一页:

决不使用scanf("%s", ...) - 决不

没有检查输入的长度,使用户可以输入要存储在缓冲区一些文本太长,你提供(例如id)。这会对你的程序造成灾难性的影响,因为它会写入数组边界之外。你的程序可能会崩溃或做各种奇怪的事情。

您应该使用fgets来阅读用户输入。它更容易,更安全。

你的主循环:

是的,原因正如你在所有case S IN的switch设置flag假它将终止。

0

以下为因而isalpha()函数的声明。

INT因而isalpha(INT C);

如果c是字母表,则此函数返回非零值,否则返回0.您的while将始终保持真实条件。它进入右边两个案例中的一个?所以一旦离开,确保你返回false或0,以便它出来。现在取决于你如何修改它。