Scanfvalidation

有人可以帮我validation我在下面的Scanf的输入。 如果Scanf在不正确的范围内或者不是整数,我希望程序要求重新输入数据。 我在使用if语句之前放入了do while循环,但是当我编译它时,第一个printf和scanf只是循环

#include  #include  int MenuLoop = 0; int MaxPackets = 4; int currentPackets= 0; int menu; /********************************************************* * Node to represent a Cat which includes a link reference* * a link list of nodes with a pointer to a Cat Struct * * would be better but this is for illustartion only! * **********************************************************/ struct Packet { int Source; int Destination; int Type; int Port; char *Data; struct Packet *next; // Link to next Cat }; typedef struct Packet node; // Removes the need to constantly refer to struct /********************************************************* * Stubs to fully declared functions below * **********************************************************/ void outputPackets(node **head); void push(node **head, node **aPacket); node* pop(node **head); void AddPacket(); void AddPacket(); void SavePacket(); void ShowCurrent(); void ExitProgramme(); main() { do{ Menu(); } while(menuSource); printf("Enter Destination Number between 1-1024:\n"); scanf("%i", &pPacket->Destination); printf("Enter Type Number between 0-10:\n"); scanf("%i", &pPacket->Type); printf("Enter Port Number between 1-1024:\n"); scanf("%i", &pPacket->Port); printf("Enter Data Numberbetween 1-50:\n"); scanf("%s", &pPacket->Data); printf("Do you want to Enter another Packet?"); pPacket->next = NULL; /********************************************************* * Push the Cat onto the selected Link List, the function * * is written so the program will support multiple link * * list if additional 'pHead' pointers are created. * * Who says you cannot herd cats! * ********************************************************** * NOTE: The push parameters are using references to the * * pointers to get round the pass by value problem caused * * by the way C handles parameters that need to be * * modified * **********************************************************/ push(&pHead, &pPacket); pPacket = (node *)malloc(sizeof(node)); if (pPacket == NULL) { printf("Error: Out of Memory\n"); exit(1); } outputPackets(&pHead); /********************************************************* * Display the Link List 'pHead' is passed as a reference * **********************************************************/ return 0; do{ if(currentPackets == MaxPackets); { printf("Packet limit reached please save\n"); } }while(currentPacketsSource, pos->Destination, pos->Type, pos->Port); pos = pos->next ; } printf("End of List\n\n"); } void push(node **head, node **aPacket) { /********************************************************* * Add the cat to the head of the list (*aCat) allows the * * dereferencing of the pointer to a pointer * **********************************************************/ (*aPacket)->next = *head; *head = *aPacket; } node *pop(node **head) { /********************************************************* * Walk the link list to the last item keeping track of * * the previous. when you get to the end move the end * * and spit out the last Cat in the list * **********************************************************/ node *curr = *head; node *pos = NULL; if (curr == NULL) { return NULL; } else { while (curr->next != NULL) { pos = curr; curr = curr->next; } if (pos != NULL) // If there are more cats move the reference { pos->next = NULL; } else { // No Cats left then set the header to NULL (Empty list) *head = NULL; } } return curr; } void SavePacket(){ FILE *inFile ; char inFileName[10] = { '\0' } ; printf("Input file name : ") ; scanf("%s", inFileName) ; //Open file inFile = fopen(inFileName, "w+"); if (!inFile) { fprintf(stderr, "Unable to open file %s", &inFile); exit(0); } //fprintf(inFile, "Source: %i Destination: %i Type: %i Port: %i \n", pos->Source, pos->Destination, pos->Type, pos->Port); fclose(inFile); } void ShowCurrent(){ } void ExitProgramme(){} void Menu(){ printf("********Welcome****** \n"); printf("Creator Ben Armstrong.\n\n"); printf("*Please Choose an option*\n"); printf("1. Add a new packet\n"); printf("2. Save current packet to file\n"); printf("3. Show current list of packets\n"); printf("4. Exit\n"); scanf("%i", &menu); switch(menu) { case 1: AddPacket(); break; case 2: SavePacket(); break; case 3 : ShowCurrent(); break; case 4 : ExitProgramme(); break; } } 

这是我的完整代码,因为你可以看到我试图实现一个必须validation数据的链接列表

使用以下宏

 #define SCAN_ONEENTRY_WITHCHECK(FORM,X,COND) \ do {\ char tmp;\ while(((scanf(" "FORM"%c",X,&tmp)!=2 || !isspace(tmp)) && !scanf("%*[^\n]"))\ || !(COND)) {\ printf("Invalid input, please enter again: ");\ }\ } while(0) 

您在本主题中找到了宏观解释

使用它的例子:

 int main() { ....... printf("Enter Source Number between 1-1024:\n"); SCAN_ONEENTRY_WITHCHECK("%i", &pPacket->Source, (pPacket->Source>=1 && pPacket->Source<=1024); printf("Enter Destination Number between 1-1024:\n"); SCAN_ONEENTRY_WITHCHECK("%i", &pPacket->Destination, (pPacket->Destination>=1 && pPacket->Destination<=1024); printf("Enter Type Number between 0-10:\n"); SCAN_ONEENTRY_WITHCHECK("%i", &pPacket->Type, (pPacket->Type>=0 && pPacket->Type<=10); printf("Enter Port Number between 1-1024:\n"); SCAN_ONEENTRY_WITHCHECK("%i", &pPacket->Port, (pPacket->Port>=1 && pPacket->Port<=1024); printf("Enter Data Numberbetween 1-50:\n"); SCAN_ONEENTRY_WITHCHECK("%i", &pPacket->Data, (pPacket->Data>=1 && pPacket->Data<=50); } 

以下是使用strtol一种方法:

 #include  #include  struct Packet { int Source; int Destination; int Type; int Port; int Data; }; void func(struct Packet *pPacket) { char entry[100]; int i; char *tail; do { printf("Enter Source Number between 1-1024:\n"); scanf("%99s", entry); i = strtol(entry, &tail, 0); } while (*tail || i < 1 || i > 1024); pPacket->Source = i; } int main(int argc, char* argv[]) { struct Packet pPacket; func(&pPacket); printf("pPacket->Source is now %i.\n", pPacket.Source); return 0; }