2012-12-04 33 views
5

नया यहाँ और मेरे पास एक बहुत ही सरल सवाल है। मैं सी में एक साधारण प्रोग्राम बना रहा हूं जिसके लिए उपयोगकर्ता को एक char के साथ क्या करना है, इस विकल्प को दर्ज करने की आवश्यकता है। परिणाम दर्ज करने के बाद, कार्यक्रम मेनू पर वापस चला जाता है। हालांकि ऐसा लगता है कि कुछ प्रकार के भूत इनपुट लेते हैं जैसे कि चार के पास कुछ अज्ञात मूल्य है। मुझे char वापस अपने डिफ़ॉल्ट स्थिति में सेट करने की आवश्यकता है।सी - उपयोगकर्ता एकल चार इनपुट अजीब परिणाम

कोड:

/* display menu for user */ 
void menu() { 

    printf("\n- - - Phone Book Database - - -\n"); 
    printf("\nSelect an action:\n\n"); 
    printf("\tc:\tCreate a database entry.\n"); 
    printf("\ts:\tSearch the database entries.\n"); 
    printf("\td:\tDelete a database entry.\n"); 
    printf("\tq:\tQuit program.\n\n"); 

    printf("Enter choice: "); 
    menu_choice = getchar(); 

    if(menu_choice != 'c' && menu_choice != 's' 
     && menu_choice != 'd' && menu_choice != 'q') { 
      printf("\n\n\tInvalid choice.\n"); 
      menu(); 
    } 
    //fflush(stdin); 
} 

यहाँ एक उदाहरण उत्पादन होता है:

- - - Phone Book Database - - - 

Select an action: 

    c: Create a database entry. 
    s: Search the database entries. 
    d: Delete a database entry. 
    q: Quit program. 

Enter choice: c 

Enter name: test 

Enter address: test 

Enter number: 3 

- - - Phone Book Database - - - 

Select an action: 

    c: Create a database entry. 
    s: Search the database entries. 
    d: Delete a database entry. 
    q: Quit program. 

Enter choice: 
    Invalid choice. 

- - - Phone Book Database - - - 

Select an action: 

    c: Create a database entry. 
    s: Search the database entries. 
    d: Delete a database entry. 
    q: Quit program. 

Enter choice: q 

ग के रूप में एक इनपुट

/* creates a new record in array */ 
void create_record() { 
    char name[MAX]; 
    char address[MAX]; 
    int number; 

    rec_num++; /* add 1 to marker for record placement */ 

    printf("\nEnter name: "); 
    scanf("%s", name); 

    printf("\nEnter address: "); 
    scanf("%s", address); 

    printf("\nEnter number: "); 
    scanf("%d", &number); 

    strcpy(record[rec_num].name, name); 
    strcpy(record[rec_num].address, address); 
    record[rec_num].number = number; 
} 
+0

'सी' चुना जाने पर आप क्या करते हैं? – Xymostech

+0

@Xymostech जब सी चुना जाता है तो यह डेटाबेस प्रविष्टि बनाने के लिए एक और फ़ंक्शन कॉल करता है। मैं प्रत्येक क्षेत्र के लिए structs की एक सरणी का उपयोग करें। यह ठीक काम करता है, लेकिन मेनू() फ़ंक्शन पर वापस जाने पर यह कुछ जवाब देता है और "अमान्य विकल्प" प्रस्तुत करता है। जैसा कि आप देख सकते हैं। –

+0

ऐसा लगता है कि अन्य फ़ंक्शन इनपुट को सही तरीके से नहीं ले रहा है, इसलिए बफर में अतिरिक्त इनपुट शेष है और जब आप मेनू पर वापस आते हैं, तो कुछ पहले ही चुना जा चुका है। क्या आप उस फ़ंक्शन के लिए कोड देख सकते हैं जिसके बारे में आपने बात की थी? – Xymostech

उत्तर

4

ऐसा लगता है कि आपका उत्तर पहले से ही है, और समीक्षा कर रहा है, यह सही है; getchar() का उपयोग करने से stdin

printf("Enter choice: "); 
menu_choice = getchar(); 

एक चरित्र पढ़ा जाएगा जब मैं कंसोल पर यह संकेत करने के लिए मिलता है और टाइप c<enter key> यह दो चार के stdin पर जाने के लिए पैदा कर रहा है: 'c' और '\n'

पहली बार getchar(); रन, यह न्यूलाइन चरित्र छोड़कर 'c' उठाता है। दूसरे पुनरावृत्ति पर '\n' उपयोगकर्ता से कुछ भी इंतजार किए बिना उठाया जाता है; ऐसा लगता है कि "भूत इनपुट" है।

मैं बस यह इंगित करना चाहता था कि जब भी आप उपयोगकर्ता से इनपुट प्राप्त कर रहे हों और नतीजे आपके द्वारा अपेक्षित नहीं हैं, तो यह सुनिश्चित करने के लिए कि यह क्या हो रहा है, इसे सत्यापित करने के लिए इसे वापस डंप करने में कोई दिक्कत नहीं होती है:

if(menu_choice != 'c' && menu_choice != 's' 
    && menu_choice != 'd' && menu_choice != 'q') { 
     printf("\n\n\tYou entered %c (%d).\n", menu_choice, menu_choice); 
     printf("\tThat's an invalid choice.\n"); 
     menu(); 
} 

आप से पता चला है चाहेंगे:

You entered 
(10). 
That's an invalid choice. 
तथ्य यह एक अलग लाइन पर था के बीच

, और यह जांच कि एक ASCII तालिका के विरुद्ध दशमलव परिणाम आप देखना चाहते हैं कि 10 न्यू लाइन चरित्र है , जो आपको नेतृत्व करने में मदद कर सकता है ओ परिणाम।

संपादित करें: एक नई पंक्ति लेने के लिए

1 विकल्प -

printf("what character?"); 
c = getchar(); // Get the character from stdin 
getchar();  // consume the newline character that was left 

एक दूसरा विकल्प:

printf("what character?"); 
scanf("%c ", &c); // Get the character from stdin, note the space after the %c 
        // that will allow any special characters including \t and \n 

तुम सिर्फ चरित्र पाने के लिए और उसके बाद & में खत्म चाहते हैं उपभोग '\n', आपको न्यूलाइन चार जोड़ना और भागना होगा:

printf("what character?"); 
scanf("%c\\n", &c); 
+0

बहुत उपयोगी। इसने मेरी समस्या का समाधान नहीं किया लेकिन इससे मुझे यह समझने में मदद मिली कि यह कैसे काम करता है। धन्यवाद! –

+1

@ जेम्स मैन्स - हाँ, मैंने वास्तव में उल्लेख नहीं किया कि * इसे कैसे ठीक किया जाए, बस क्या हो रहा था ... पीछे की ओर मैंने आपकी रुचि के लिए कुछ "त्वरित" फिक्स जोड़े (मेरी पोस्ट में संपादित देखें)। दूसरा विकल्प बेहतर है क्योंकि यह अधिक लचीलापन – Mike

+0

के लिए अनुमति देता है मैंने इसे देखा और मैंने getchar() विकल्प का उपयोग करना शुरू कर दिया। स्कैनफ़ का उपयोग करना ("% c" &c"); असफल रहा। चयन करने के लिए एंटर मारने के बाद यह टर्मिनल में एक नई लाइन बनायेगा। मैं कुछ भी नहीं के साथ एंटर दबाकर रख सकता हूं लेकिन नई लाइनों को आउटपुट किया जा रहा है। –

-1

एक आवारा चरित्र, लगभग निश्चित रूप से 'कॉल निम्नलिखित समारोह में प्रवेश कर \ n ', आपके इनपुट कमांड के बाद आपके इनपुट बफर पर छोड़ा गया है।

इसे हटाने के लिए, आप जोड़ सकते हैं:

fflush(stdin) 

... सही अपने getchar() कॉल करने से पहले।

+0

मैंने कोशिश की और यह काम नहीं करता है। मैं fflush (stdin) का उपयोग करके सुनता हूं इस तरह की स्थितियों में बहुत अनुचित है। –

+1

@JamesManes C99 7.21.5.2p2, आउटपुट स्ट्रीम, एक अपडेट स्ट्रीम, या NULL के अलावा कुछ भी fflushing, अपरिभाषित व्यवहार है, न केवल "अनुचित"। [ऐसा मत करो] (http://stackoverflow.com/questions/2979209/using-fflushstdin)। – WhozCraig

+0

@WozozCraig नहीं पता था कि यह अपरिभाषित व्यवहार था।में इसे याद रखूंगा। आपको आश्चर्य होगा कि कितने लोगों ने मुझे अन्य साइटों पर सुझाव दिया है! –

0

रिटर्न चार '\ n' शायद stdin में छोड़ा जा रहा है ताकि अगली बार जब आप इसके आसपास आ सकें getchar() इसे ला रहा है।

getchar() के साथ या तो डिबगर के साथ या केवल इसे प्रिंट करके प्राप्त मूल्य को देखने का प्रयास करें।

हो सकता है कि getchar() आपके आवेदन के लिए एक उपयुक्त विकल्प नहीं है और कहा कि scanf() एक बेहतर काम करना होगा, कि जिस तरह से stdin के सभी प्राप्त किए गए हो जाएगा और यह खाली अगली बार जब आप के आसपास आ जाना चाहिए। जाहिर है, आपको अपने दूसरे कोड में भी लिखने के लिए एक से अधिक char के साथ स्कैनफ प्रदान करना होगा।

फिर आप अपने चार प्राप्त करने के लिए सरणी में पहले चार को देख सकते हैं।

2

जैसा कि अन्य ने बताया है, यह न्यूलाइन चरित्र है। बस एक और

(void) getchar(); /* read and discard newline */ 

जहां कहीं भी आप केवल एक वर्ण पढ़ना चाहते हैं।

+0

आपको बहुत धन्यवाद। मैंने इसे प्रत्येक फंक्शन के अंत में जोड़ा और यह मेरी समस्या को पूरी तरह से ठीक कर दिया। यह सबसे अच्छा तरीका नहीं हो सकता है, लेकिन यह काम करता है। मैं एक और समाधान की तलाश करूंगा लेकिन इस दौरान इसका इस्तेमाल करूंगा। –