Validação Scanf

Alguém pode me ajudar a validar as inputs para o Scanf que eu tenho abaixo. Eu quero que o programa peça que os dados sejam reinseridos se os Scanf’s estiverem dentro de um intervalo incorreto ou não em um interger. Eu coloquei um do while loop antes com uma instrução if, mas quando eu compilei o primeiro printf e scanf apenas em loop

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

Este é o meu código completo, como você pode ver im tentando implementar uma lista de links que os dados têm de ser validados para

Use a macro a seguir

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

Você encontra neste tópico a explicação macro

Exemplo de uso:

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

Aqui está uma abordagem usando 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; }