开发者

How do I get user input without using scanf in a console app?

开发者 https://www.devze.com 2022-12-21 01:54 出处:网络
I\'m trying to allow users to simply hit Enter without typing anything, and use this to mean accepting a default value.scanf isn\'t doing what I want and the app st开发者_如何学运维ill \'blocks\': the

I'm trying to allow users to simply hit Enter without typing anything, and use this to mean accepting a default value. scanf isn't doing what I want and the app st开发者_如何学运维ill 'blocks': the next line of code doesn't run.

The only way is to actually type something THEN press Enter.

I tried using NSFileHandle and fileHandleWithStandardInput; however, it seems that the user is now forced to hit Ctrl-D to indicate EOF.

Someone suggested using fgets, but I cannot work out what to pass as 3rd parameter (of FILE* type). Tried stdin but it doesn't 'block'.

How do I accept input from a user, using Objective-C, and at the same time allow the user to simply hit Enter without being forced to type anything? How do I read a single line, even if that line is blank?


Assuming the code doesn't block and the next line runs immediately (as you seemed to indicate early in the question and in a comment), you have a common problem when mixing non-line-based and line-based input.

What happens is you have a newline left in the buffer, and fgets sees that, reads it, and returns, instead of doing what you really want: ignoring it, and then reading a line.

The solution is to simply do the ignoring part yourself, and then call fgets:

#include <stdio.h>
#include <string.h>

FILE* ignoreline(FILE* stream) {
  for (int c; (c = fgetc(stream)) != EOF;) {
    if (c == '\n') break;
  }
  return stream;
}

void example_use() {
  char buf[1000];
  ignoreline(stdin);
  fgets(buf, sizeof buf, stdin);
  // or, since it returns the stream, can be more compact:
  fgets(buf, sizeof buf, ignoreline(stdin));
}

int main() { // error handling omitted
  int n;
  printf("Enter a number: ");
  scanf("%d", &n);

  char buf[1000];
  printf("Enter a line: ");
  ignoreline(stdin); // comment this line and compare the difference
  fgets(buf, sizeof buf, stdin);
  *strchr(buf, '\n') = '\0';
  printf("You entered '%s'.\n", buf);

  return 0;
}

Note that it is also common and encouraged to "pair" the ignoreline with the scanf (or other non-line-based input) to turn that into line-based input. You may want to modify it, in that case, so you can tell the difference between input of "42 abc" and "42" (in the "Enter a number" case). Some people just use fgets everywhere, then parse that line with sscanf, and while that works, it's not necessary.


I use getch(); in library conio.h simply the program waits for any key to be pressed


If you're using Windows, you can use the ReadConsoleInput function (see MSDN for more on this) :

INPUT_RECORD keyin;
DWORD r;

    while (ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE),&keyin,1,&r)) {

    if (keyin.EventType!=KEY_EVENT) continue;
    if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_SPACE) break;    ///use these VK codes to get any key's input

    if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_F1)            
    {
       printf("You pressed F1\n");
    }

    if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_F2)            
    {
        printf("You pressed F2\n",);
    }

    }//end while loop

You don't need to hit enter after each key then.This works like a dream for me...


use getchar() to take input without using scanf function...

0

精彩评论

暂无评论...
验证码 换一张
取 消