कैसे जारी रखने के लिए "कोई भी कुंजी दबाएं?"


87

मैं एक C ++ प्रोग्राम लिखने की कोशिश कर रहा हूं जिसमें जब उपयोगकर्ता कीबोर्ड से किसी भी वर्ण में प्रवेश करता है और उसे कोड की अगली पंक्ति में जाना चाहिए।

यहाँ मेरा कोड है:

char c;

cin>>c;

cout<<"Something"<<endl;

लेकिन यह काम नहीं कर रहा है, क्योंकि यह केवल अगली पंक्ति में जाता है जब मैं कुछ वर्ण इनपुट करता हूं और फिर ENTER दबाता हूं।

या

अगर मैं इसका उपयोग करता हूं

cin.get() or cin.get(c)

जब मैं Enter दबाता हूं तो यह निर्देश की अगली पंक्ति में चला जाता है।

लेकिन मैं चाहता था कि यह कीबोर्ड पर दबाए गए किसी भी कुंजी पर अगली पंक्ति में जाए, यह कैसे किया जा सकता है?


जहाँ तक मुझे पता है, समस्या यह है, कि आपका शेल आपके लिए ENTER या EOF दबाने का इंतजार कर रहा है और फिर आपके प्रोग्राम को बफर या इस तरह से जो कुछ भी है, उसका ध्यान रखने देगा। हो सकता है कि कुछ और ज्ञान के साथ कोई व्यक्ति वास्तविक स्पष्टीकरण दे सके। लेकिन मुझे लगता है कि यह उतना आसान नहीं है जितना कि यह पहली बार दिखाई देता है।
लुकास

7
अब तक इसे संभालने का सबसे आसान तरीका और एकमात्र पोर्टेबल तरीका है, अपने प्रॉम्प्ट को "जारी रखने के लिए कोई भी कुंजी दबाएं" से "बदलने के लिए Enter कुंजी दबाएं"।
बजे लूटना

@ लुकास - मैं एक्सकोड के साथ मैक का उपयोग कर रहा हूं।
इसके बारे में

@ लुकास: यह शेल नहीं है, यह कार्यक्रम ही है।
कीथ थॉम्पसन

@KeithThompson: यह दो साल से अधिक समय पहले का है, लेकिन मुझे लगता है कि मैं इस बात को बनाने की कोशिश कर रहा था कि इनपुट कतार उपयोगकर्ता प्रक्रिया द्वारा नहीं बल्कि कर्नेल के अंदर संभालेगी।
लुकास

जवाबों:


64

विंडोज पर:

system("pause");

और मैक और लिनक्स पर:

system("read");

आउटपुट "जारी रखने के लिए कोई भी कुंजी दबाएं ..." और जाहिर है, किसी भी कुंजी को दबाए जाने की प्रतीक्षा करें। मुझे आशा है कि आप क्या मतलब है


5
systemबाहरी कार्यक्रम कहता है। किसी भी कुंजी की प्रतीक्षा करने के लिए आपको बाहरी प्रोग्राम को कॉल करने की आवश्यकता नहीं है! जब आप इसके सामने बैठे हों तो यह आपके कंप्यूटर को चालू करने के लिए किसी अन्य व्यक्ति को कॉल करने जैसा है - यह धीमा समाधान है।
जिंजरप्लस

8
सच है, लेकिन यह केवल एक पंक्ति लंबी है! कभी-कभी यह केवल कुछ चक्रों को कंप्यूटर को बचाने के प्रयास के लायक नहीं होता है ...
इलियट कैमरन

14
धीमी गति से भूल जाओ, यह पहला कार्यक्रम कहता है जिसे "ठहराव" कहा जाता है, यह पथ में खोजने के लिए होता है, और इसे कॉलिंग कार्यक्रम का विशेषाधिकार स्तर देता है। यहां तक ​​कि अगर आप एक छात्र सिर्फ अपने कोड का परीक्षण कर रहे हैं, यह अभी भी एक बड़े पैमाने पर सुरक्षा जोखिम है।
ऐनी क्विन

6
@XDfaceme - पॉज़ एक वास्तविक कार्यक्रम है जो सिस्टम () विंडोज़ को चलाने के लिए कहता है। हालाँकि, 'पॉज़' नामक एक और प्रोग्राम है और विंडोज़ को वह प्रोग्राम पहले मिल जाता है, तो वह इसके बजाय इसे चलाएगा। मुझे लगता है कि मैंने महत्व को थोड़ा कम कर दिया है, लेकिन अभी भी सिर्फ cin.get () का उपयोग करना आसान है और एक कार्यक्रम को रोकने / वापस करने के लिए हिट मारा
ऐनी क्विन

2
मैं निरपेक्षता का प्रशंसक नहीं हूं। एक कंबल बयान करना कि प्रणाली ("ठहराव") एक सुरक्षा जोखिम है और यह तब भी बुरा है जब अपने स्वयं के कोड का परीक्षण करना यहां चीजों को अनुपात से बाहर उड़ा रहा है। cin.get () सही समाधान हो सकता है, लेकिन यह उस प्रश्न को हल नहीं करता है जो पूछा जा रहा था ... cin.get () केवल "दर्ज" या "वापसी" के बाद प्रतिक्रिया करता है। सवाल विशेष रूप से किसी भी कुंजी प्रेस का जवाब देने के लिए था। सिस्टम ("विराम") ठीक यही करता है। सबसे पहले, एकमात्र जगह जहां मैंने इसे उपयोगी के रूप में देखा है जब विज़ुअल स्टूडियो से डीबगिंग करते समय एक देव वर्ग में है, तो मुझे लगता है कि सिस्टम ("ठहराव") काम करता है
ग्रेगर

52

यदि आप विंडोज पर हैं, तो आप उपयोग कर सकते हैं kbhit()जो Microsoft रन-टाइम लाइब्रेरी का हिस्सा है। यदि आप लिनक्स पर हैं, तो आप kbhitइस प्रकार ( स्रोत ) लागू कर सकते हैं :

#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

int kbhit(void)
{
  struct termios oldt, newt;
  int ch;
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  ch = getchar();

  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);

  if(ch != EOF)
  {
    ungetc(ch, stdin);
    return 1;
  }

  return 0;
}

अद्यतन: उपरोक्त फ़ंक्शन ओएस एक्स पर काम करता है (कम से कम, ओएस एक्स 10.5.8 - तेंदुए पर, इसलिए मुझे उम्मीद है कि यह ओएस एक्स के अधिक हाल के संस्करणों पर काम करेगा)। इस जिस्ट को kbhit.cलिनक्स और OS X दोनों के साथ संकलित किया जा सकता है

gcc -o kbhit kbhit.c

जब साथ चलाया जाए

./kbhit

यह आपको एक कुंजीपट के लिए प्रेरित करता है, और जब आप कुंजी दबाते हैं (तो प्रवेश या मुद्रण योग्य कुंजी तक सीमित नहीं) से बाहर निकलता है।

@ जॉनोवेब - कृपया "विस्तृत विहित उत्तर" और "सभी चिंताओं" से आपका क्या अभिप्राय है। इसके अलावा, फिर से "क्रॉस-प्लेटफ़ॉर्म": kbhit()आप के इस कार्यान्वयन के साथ लिनक्स / यूनिक्स / ओएस एक्स / विंडोज पर सी ++ प्रोग्राम में समान कार्यक्षमता हो सकती है - आप किन अन्य प्लेटफार्मों का उल्लेख कर सकते हैं?

@ जोंसविएब के लिए और अपडेट: सी ++ एप्लिकेशन एक सीमांकित सी ++ वातावरण में नहीं रहते हैं। सी ++ की सफलता का एक बड़ा कारण सी के साथ अंतर-निर्भरता है। सभी मुख्यधारा के प्लेटफार्मों को सी इंटरफेस (भले ही आंतरिक कार्यान्वयन सी ++ का उपयोग कर रहा है) के साथ लागू किया जाता है, इसलिए आपकी "विरासत" की बात जगह से बाहर लगती है। इसके अलावा, जैसा कि हम एक एकल फ़ंक्शन के बारे में बात कर रहे हैं, आपको इसके लिए C ++ ("सी विद क्लासेस") की आवश्यकता क्यों है? जैसा कि मैंने बताया, आप C ++ में लिख सकते हैं और इस कार्यक्षमता तक आसानी से पहुँच सकते हैं, और आपके एप्लिकेशन के उपयोगकर्ताओं को परवाह नहीं है कि आपने इसे कैसे लागू किया है।


यह शर्म की बात है कि कंसोल को संभालने के लिए कोई मानक तरीका नहीं है, आपको हमेशा कुछ ओएस मैजिक का उपयोग करना होगा
वर्गास

1
@Johnsyweb: धन्यवाद आप , लेकिन अपने उदाहरण से पता चलता है विशेषताएं है कि मुझे सी के बारे में दबाना ++। आपका kbhit()फ़ंक्शन terminal_settingsएक पंक्ति में एक चर घोषित करता है जो कुछ भी नहीं करता प्रतीत होता है, और फिर भी यह सब कुछ करता है। कुछ लोग सोच सकते हैं कि यह साफ-सुथरा है, लेकिन मुझे लगता है कि यह अपठनीयता के मुद्दे पर अस्पष्ट है।
विनय साजिप

1
@VinaySajip: मेरा कार्यान्वयन RAII का उपयोग करता है , जो C ++ में सबसे महत्वपूर्ण मुहावरों में से एक है। जबकि इस उदाहरण में यह कड़ाई से आवश्यक नहीं है, मैंने इसे एक अच्छी आदत में पाया है जब आप कुछ राज्य को बचाना चाहते हैं और इसे पुनर्स्थापित करना चाहते हैं।
जॉन्सवेब

4
@ जॉनोवेब: मैं आरएआई से अवगत हूं और इससे होने वाले लाभ, मैं खुद एक पुराना सी ++ हूं। मेरी बात बनी हुई है: घोषणा के बीच कोई स्पष्ट संबंध नहीं है और यह पर्दे के पीछे क्या कर रहा है। हालांकि यह सादे पुराने सी के बजाय चमकदार सी ++ मुहावरों का उपयोग कर सकता है, मेरा विचार है कि यह रोशन करने के लिए बहुत कम है और जो कुछ चल रहा है उसे अस्पष्ट करने के लिए बहुत कुछ करता है। यह आपको किसी भी तरह से व्यक्तिगत रूप से निर्देशित नहीं किया गया है - यह सिर्फ एक राय है कि सी + + का उपयोग कोड बनाने के लिए कैसे किया जा सकता है जो समझने में अनावश्यक रूप से कठिन है। मैं अपना साबुनबॉक्स बंद कर दूंगा, 'नफ ने कहा।
विनय साजिप

2
यह अच्छा है और सभी है, लेकिन फिर भी स्टड पर कोई भी पिछला कचरा पकड़ता है :-)
टियागो

8

पूरी तरह से पोर्टेबल समाधान नहीं है।

Comp.lang.c का प्रश्न 19.1 , कुछ गहराई में विंडोज, यूनिक्स जैसे सिस्टम और यहां तक ​​कि MS-DOS और VMS के समाधान के साथ इसे शामिल करता है।

एक त्वरित और अपूर्ण सारांश:

  • आप cursesपुस्तकालय का उपयोग कर सकते हैं ; cbreak()इसके बाद कॉल करें getch()(विंडोज-विशिष्ट getch()फ़ंक्शन के साथ भ्रमित होने की नहीं )। ध्यान दें कि cursesआम तौर पर टर्मिनल का नियंत्रण होता है, इसलिए यह ओवरकिल होने की संभावना है।
  • आप ioctl()टर्मिनल सेटिंग्स में हेरफेर करने के लिए उपयोग करने में सक्षम हो सकते हैं।
  • POSIX- आज्ञाकारी प्रणालियों पर, tcgetattr()और tcsetattr()एक बेहतर समाधान हो सकता है।
  • यूनिक्स पर, आप कमांड system()को लागू करने के लिए उपयोग कर सकते हैं stty
  • MS-DOS पर, आप उपयोग getch()या कर सकते हैं getche()
  • VMS (जिसे अब OpenVMS कहा जाता है) पर, स्क्रीन मैनेजमेंट ( SMG$) रूटीन ट्रिक कर सकता है।

इन सभी C समाधानों को C ++ में समान रूप से अच्छी तरह से काम करना चाहिए; मैं किसी भी सी + + विशिष्ट समाधान के बारे में नहीं जानता।


ये सभी बहु-प्लेटफ़ॉर्म समाधान किसी फ़ंक्शन को लिखने के साथ कर सकते हैं जो कि आपके प्लेटफ़ॉर्म पर निर्भर करने के लिए बहुत सारे प्री-प्रोसेसर के साथ सही काम करने के लिए कार्यान्वित किया जाता है।
कैशोकॉ

6

इस कार्यक्षमता को प्राप्त करने के लिए आप ncurses लाइब्रेरी का उपयोग कर सकते हैं जो कि विंडोज़ और लिनक्स (और जहाँ तक मुझे पता है) पर लागू किया गया था।


वैसे यह एक तरह का असाइनमेंट है जिसमें मैं किसी बाहरी लाइब्रेरी आदि का उपयोग नहीं कर सकता, इसलिए बस "अध्याय संदर्भ" लक्स में रहना होगा।
इसकाबाउटकोड

2
फिर एक ही विकल्प है कि आप जिस प्रत्येक ओएस का समर्थन करने की योजना बना रहे हैं, उसके लिए आवश्यक कार्यक्षमता को लागू करें।
किरिल वी। लयाडविंस्की

1
ncurses कमोबेश VT200 ग्राहक हैं। TTY से पढ़ने के लिए थोड़ा ओवरकिल।
ग्रेफेड

5

खिड़कियों में, यह छोटा कार्यक्रम लक्ष्य को पूरा करता है: getchकुंजी दबाए जाने तक कंसोल को रोक देता है ( https://www.geeksforgeeks.org/difference-getchar-getch-getc-getche/ )

#include<iostream.h>
#include<conio.h>

using namespace std;

void  check()
{
    char chk; int j;
    cout<<"\n\nPress any key to continue...";
    chk=getch();
    j=chk;
    for(int i=1;i<=256;i++)
      if(i==j) break;
    clrscr();
}

void main()
{
    clrscr();
    check();
    cout<<"\n\nIt works!";
    getch();
}

यह ध्यान दिया जाना चाहिए कि getch मानक पुस्तकालय का हिस्सा नहीं है।


1
यह बहुत ही सरल कार्यक्रम है। यह समझने में बहुत आसान है
बोल्डएक्स

1
कृपया बताएं कि कैसे getch()अलग है, cin.getया cin>>शायद प्रलेखन के लिए कुछ लिंक
user2622016

1
conio केवल विंडोज पर है
एंड्रयू वुल्फ

4

मैंने देखा कि आप क्या हासिल करने की कोशिश कर रहे हैं, क्योंकि मुझे याद है कि मैं वही काम करना चाहता था। विनय से प्रेरित होकर मैंने कुछ ऐसा लिखा जो मेरे लिए काम करता है और मैं इसे समझता हूं। लेकिन मैं कोई विशेषज्ञ नहीं हूं, इसलिए कृपया सावधान रहें।

मुझे नहीं पता कि विनय कैसे जानता है कि आप मैक ओएस एक्स का उपयोग कर रहे हैं। लेकिन इसे सबसे अधिक यूनिक्स जैसे ओएस के साथ इस तरह का काम करना चाहिए। संसाधन opengroup.org के रूप में वास्तव में उपयोगी है

फ़ंक्शन का उपयोग करने से पहले बफर को फ्लश करना सुनिश्चित करें।

#include <stdio.h>
#include <termios.h>        //termios, TCSANOW, ECHO, ICANON
#include <unistd.h>     //STDIN_FILENO


void pressKey()
{
    //the struct termios stores all kinds of flags which can manipulate the I/O Interface
    //I have an old one to save the old settings and a new 
    static struct termios oldt, newt;
    printf("Press key to continue....\n");

    //tcgetattr gets the parameters of the current terminal
    //STDIN_FILENO will tell tcgetattr that it should write the settings
    // of stdin to oldt
    tcgetattr( STDIN_FILENO, &oldt);
    //now the settings will be copied 
    newt = oldt;

    //two of the c_lflag will be turned off
    //ECHO which is responsible for displaying the input of the user in the terminal
    //ICANON is the essential one! Normally this takes care that one line at a time will be processed
    //that means it will return if it sees a "\n" or an EOF or an EOL
    newt.c_lflag &= ~(ICANON | ECHO );      

    //Those new settings will be set to STDIN
    //TCSANOW tells tcsetattr to change attributes immediately. 
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);

    //now the char wil be requested
    getchar();

    //the old settings will be written back to STDIN
    tcsetattr( STDIN_FILENO, TCSANOW, &oldt);

}


int main(void)
{
  pressKey();
  printf("END\n");
  return 0;
}

O_NONBLOCK भी एक महत्वपूर्ण ध्वज लगता है, लेकिन इसने मेरे लिए कुछ भी नहीं बदला।

मैं सराहना करता हूं कि अगर कुछ गहन ज्ञान वाले लोग इस पर टिप्पणी करेंगे और कुछ सलाह देंगे


O_NONBLOCK सेट किया जाना चाहिए क्योंकि इसके बिना, getchar () (जो कॉल पढ़ता है ()) इनपुट के लिए प्रतीक्षा को अवरुद्ध करेगा। Kbhit () समाधान बताता है कि क्या आप एक कुंजी हिट कर रहे हैं, प्रतीक्षा किए बिना; आप इसे एक प्रतीक्षा लूप या किसी अन्य उद्देश्य के लिए उपयोग कर सकते हैं, इसलिए यह अधिक सामान्य समाधान है। O_NONBLOCK के बिना एक समाधान एक कुंजी हिट होने तक इंतजार करेगा - इस प्रश्न के लिए ठीक है लेकिन आम तौर पर कम उपयोगी है।
विनय साजिप

4

आप Microsoft-विशिष्ट फ़ंक्शन _getch का उपयोग कर सकते हैं :

#include <iostream>
#include <conio.h>
// ...
// ...
// ...
cout << "Press any key to continue..." << endl;
_getch();
cout << "Something" << endl;

3

यह एक विंडोज प्लेटफ़ॉर्म पर काम करता है: यह माइक्रोप्रोसेसर रजिस्टरों को सीधे उपयोग करता है और कुंजी प्रेस या माउसबटन की जांच के लिए इस्तेमाल किया जा सकता है

    #include<stdio.h>
    #include<conio.h>
    #include<dos.h>
    void main()
    {
     clrscr();
     union REGS in,out;
     in.h.ah=0x00;
     printf("Press any key : ");

     int86(0x16,&in,&out);
     printf("Ascii : %d\n",out.h.al);
     char ch = out.h.al;
     printf("Charcter Pressed : %c",&ch);
     printf("Scan code : %d",out.h.ah);
     getch();
    }

3

यदि आप Visual Studio 2012 या पुराने का उपयोग getch()कर रहे हैं, तो फ़ंक्शन का उपयोग करें , यदि आप Visual Studio 2013 या नए का उपयोग कर रहे हैं, तो उपयोग करें _getch()। आपको उपयोग करना पड़ेगा #include <conio.h>। उदाहरण:

#include <iostream>
#include <conio.h>

int main()
{
   std::cout << "Press any key to continue. . .\n";
   _getch(); //Or getch()
}

1

आप गेटचार रूटीन का उपयोग कर सकते हैं ।

उपरोक्त लिंक से:

/* getchar example : typewriter */
#include <stdio.h>

int main ()
{
  char c;
  puts ("Enter text. Include a dot ('.') in a sentence to exit:");
  do {
    c=getchar();
    putchar (c);
  } while (c != '.');
  return 0;
}

3
मुझे नहीं लगता कि यह वही है जो ओपी के लिए पूछ रहा था, अगर मैं उसे सही ढंग से समझता हूं। अब भी आपको getchar () से पढ़ने से पहले बफर को भरने के लिए ENTER दबाना होगा।
लुकास

0

इसके अलावा आप conio.h से getch () का उपयोग कर सकते हैं। सिर्फ इस तरह:

...includes, defines etc
void main()
{
//operator
getch(); //now this function is waiting for any key press. When you have pressed its     just     //finish and next line of code will be called
}

इसलिए, क्योंकि UNIX में conio.h नहीं है, इसलिए हम इस कोड द्वारा getch () का अनुकरण कर सकते हैं (लेकिन यह कोड पहले से ही वाइस द्वारा लिखा गया है, मेरी असफलता):

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

int mygetch( ) {
  struct termios oldt,
             newt;
  int            ch;
  tcgetattr( STDIN_FILENO, &oldt );
  newt = oldt;
  newt.c_lflag &= ~( ICANON | ECHO );
  tcsetattr( STDIN_FILENO, TCSANOW, &newt );
  ch = getchar();
  tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
  return ch;
}

-1

यदि आप MSDN पर अब kbhit () फ़ंक्शन को देखते हैं, तो यह कहता है कि फ़ंक्शन को हटा दिया गया है। इसके बजाय _kbhit () का उपयोग करें।

#include <conio.h>
int main()
{
    _kbhit();
    return 0;
}

-1
#include <iostream>
using namespace std;

int main () {
    bool boolean;
    boolean = true;

    if (boolean == true) {

        cout << "press any key to continue";
        cin >> boolean;

    }
    return 0;
}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.