2013-05-07 31 views
2

有人可以幫助我確認輸入的SCANF的,我有以下。如果Scanf位於不正確的範圍內或不是整數,我希望程序要求重新輸入數據。我把一個do while循環之前,if語句,但是當我編譯它的第一個printf和scanf只是循環SCANF驗證

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



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(menu<4); 


} 


void AddPacket(){ 

int option; 





/********************************************************* 
* pointers for the link list and the temporary P to * 
* insert into the list         * 
**********************************************************/ 
node *pPacket, *pHead = NULL; 

/********************************************************* 
* Create a cat and also check the HEAP had room for it * 
**********************************************************/ 
pPacket = (node *)malloc(sizeof(node)); 
if (pPacket == NULL) 
{ 
    printf("Error: Out of Memory\n"); 
    exit(1); 
} 

currentPackets++; 
printf("Enter Source Number between 1-1024:\n"); 
scanf("%i", &pPacket->Source); 
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(currentPackets<MaxPackets); 

return 0; 
} 




void outputPackets(node **head) 
{ 


/********************************************************* 
* Copy Node pointer so as not to overwrite the pHead  * 
* pointer            * 
**********************************************************/ 
node *pos = *head; 

/********************************************************* 
* Walk the list by following the next pointer   * 
**********************************************************/ 
while(pos != NULL) { 
    printf("Source: %.4i Destination: %.4i Type: %.4i Port: %.4i \n", pos->Source, 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; 



} 


} 

這是我的全部代碼可以看出U IM試圖實現一個鏈接列表,它的數據已被驗證爲

+0

同樣與http://stackoverflow.com/questions/15792984/common-macro-to-read-input-data-並檢查其通有效性 – MOHAMED 2013-05-07 15:54:55

+0

查看[此類似的問題(http://stackoverflow.com/questions/9462780/in-c-how-can-i-restrict-the-accepted-values-that-this- scanf的意志禁漁)。我認爲你應該製作一個函數,將你的int範圍作爲參數,然後執行readline()/ sscanf()循環,如該文章的答案中所示,並且可以管理轉義序列。另外,當你要求一個數字時,你是否真的有意爲'&pPacket-> Data'設置「%s」?用我在我的答案 – n0741337 2013-05-07 16:28:11

+0

你能告訴我們的代碼,代碼運行而不會觸發while循環 – MOHAMED 2013-05-07 16:48:36

回答

0

使用下面的宏

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

您在本topic找到宏交代的

例使用它:

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

} 
+2

downvoter你能解釋一下嗎? – MOHAMED 2013-05-07 15:55:15

+0

這將返回答案,說#define scan_onentry_withcheck未在我的函數內聲明,並且期望;在輸入的末尾 – user1949280 2013-05-07 16:16:39

+0

@ user1949280分享您的代碼以查看您的問題。您可以在問題中刪除整個代碼 – MOHAMED 2013-05-07 16:20:10

0

這裏使用strtol一種方法:

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

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