C语言 在 C 中获取用户输入的最简单方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7831755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 09:56:49  来源:igfitidea点击:

What is the simplest way of getting user input in C?

cinputioscanf

提问by antonpug

There seem to be a LOT of ways you can get user input in C.

似乎有很多方法可以在 C 中获取用户输入。

What is the easiest way that requires little code?

需要很少代码的最简单方法是什么?

Basically I need to display this:

基本上我需要显示这个:

Enter a file name: apple.text

Basically I need to ask the user for a file name. So I need something that just gets that one word that the user will be inputting.

基本上我需要向用户询问文件名。所以我需要一些东西来获取用户将输入的那个词。

回答by HostileFork says dont trust SE

The simplest "correct"way is probably this one, taken from Bjarne Stroustrup's paper Learning Standard C++ As A New Language.

最简单的“正确”方法可能是这个,取自 Bjarne Stroustrup 的论文Learning Standard C++ As A New Language

(Note: I changed Bjarne's code to check for isspace()instead of just end of line. Also, due to @matejkramny's comment, to use while(1)instead of while(true)...and so long as we're being heretical enough to edit Stroustrup's code, I've subbed in C89 comments instead of C++ style too. :-P)

(注意:我改变了 Bjarne 的代码来检查isspace()而不是仅仅检查行尾。另外,由于@matejkramny 的评论,使用while(1)而不是while(true)......只要我们足够异端来编辑 Stroustrup 的代码,我已经也用 C89 注释代替了 C++ 风格。:-P)

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

void quit() /* write error message and quit */
{
    fprintf(stderr, "memory exhausted\n");
    exit(1);
}

int main()
{
    int max = 20;
    char* name = (char*) malloc(max); /* allocate buffer */
    if (name == 0) quit();

    printf("Enter a file name: ");

    while (1) { /* skip leading whitespace */
        int c = getchar();
        if (c == EOF) break; /* end of file */
        if (!isspace(c)) {
             ungetc(c, stdin);
             break;
        }
    }

    int i = 0;
    while (1) {
        int c = getchar();
        if (isspace(c) || c == EOF) { /* at end, add terminating zero */
            name[i] = 0;
            break;
        }
        name[i] = c;
        if (i == max - 1) { /* buffer full */
            max += max;
            name = (char*) realloc(name, max); /* get a new and larger buffer */
            if (name == 0) quit();
        }
        i++;
    }

    printf("The filename is %s\n", name);
    free(filename); /* release memory */
    return 0;
}

That covers:

这包括:

  • skipping whitespace until you reach character input
  • expanding the string buffer dynamically to fit arbitrary size strings
  • handling conditions of when memory can't be allocated
  • 跳过空格直到到达字符输入
  • 动态扩展字符串缓冲区以适应任意大小的字符串
  • 无法分配内存时的处理条件

Are there simpler but broken solutions, which might even run a bit faster? Absolutely!!

是否有更简单但破碎的解决方案,甚至可能运行得更快一点?绝对地!!

If you use scanf into a buffer with no limit on the read size, then your input exceeds the size of the buffer, it will create a security hole and/or crash.

如果您使用 scanf 进入一个对读取大小没有限制的缓冲区,那么您的输入超过了缓冲区的大小,它将产生安全漏洞和/或崩溃。

Limiting the size of the reading to, say, only 100 unique characters of a filename might seem better than crashing. But it can be worse; for instance if the user meant (...)/dir/foo/bar.txtbut you end up misinterpreting their input and overwriting a file called bar.twhich perhaps they cared about.

将读取的大小限制为文件名的 100 个唯一字符似乎比崩溃更好。但情况可能更糟;例如,如果用户的意思是(...)/dir/foo/bar.txt但你最终误解了他们的输入并覆盖了一个bar.t他们可能关心的文件。

It's best to get into good habits early in dealing with these issues. My opinionis that if your requirements justify something close-to-the-metal and "C-like", it's well worth it to consider the jump to C++. It was designed to manage precisely these concerns--with techniques that are robust and extensible, yet still perform well.

最好在处理这些问题时尽早养成良好的习惯。 我的观点是,如果您的需求证明了一些接近金属和“类 C”的东西是合理的,那么考虑跳转到 C++ 是非常值得的。它旨在精确地管理这些问题——使用健壮和可扩展但仍然表现良好的技术。

回答by karrick

scanfseems to work in a non-hostile environment. In other words, you're making a simple utility program for yourself.

scanf似乎在非敌对环境中工作。换句话说,您正在为自己制作一个简单的实用程序。

BUFSIZ usually far exceeds the size limits of UNIX pathnames.

BUFSIZ 通常远远超出 UNIX 路径名的大小限制。

#include <stdio.h>

int main(void) {
  char str[BUFSIZ];                                                                                                                                                                             

  printf("Enter a file name: ");                                                                                                                                                                
  scanf("%s", str);                                                                                                                                                                             

  printf("You entered: %s\n", str);                                                                                                                                                             
}

If you need to accumulate data in a program that could be the target of buffer overrun, you might need a bit more.

如果您需要在程序中累积可能成为缓冲区溢出目标的数据,您可能需要更多。

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

char * prompt_and_read(const char * prompt) {
  char * response;
  char * bufsize;

  printf("%s", prompt);
  asprintf(&bufsize, "%%%us", BUFSIZ);

  if((response = malloc(BUFSIZ + 1)) == NULL) {
    fprintf(stderr,"out of memory\n");
    exit(1);
  }
  scanf(bufsize, response);
  free(bufsize);
  return response;
}

int main ( void ) {
  char * pathname;

  pathname = prompt_and_read("Enter a file name: ");
  printf("You entered: [%s]\n", pathname);
  free(pathname);

  return 0;
}

回答by Tio Pepe

#include <stdio.h>
int main(void)
{
    char file[100];
    printf("File Name?: \n");
    fgets(file, 100, stdin);
    printf("Your input: %s", file);
}

回答by AusCBloke

you should write your own fgets() wrapper function that reads a line of input into a buffer of a specified size and that removes the newline char that fgets() also reads. you could also return a status of whether or not the whole line was able to fit into the buffer (ie. is the newline at the end of the buffer). you shouldn't ever really use scanf or gets unless you want overflows.

您应该编写自己的 fgets() 包装函数,该函数将一行输入读取到指定大小的缓冲区中,并删除 fgets() 也读取的换行符。您还可以返回整行是否能够放入缓冲区的状态(即缓冲区末尾的换行符)。除非您想要溢出,否则您不应该真正使用 scanf 或 gets。

EDIT: thought i might provide some basic code:

编辑:以为我可能会提供一些基本代码:

typedef unsigned char BOOL;
#define TRUE   1
#define FALSE  0

/* wraps fgets, returns FALSE if the whole line couldn't fit into the buffer */
BOOL read_input(char *dest, size_t len)
{
   /* our temp buffer needs to hold the extra new line char (len + 1)
        * should also add error checking to malloc */
   BOOL bSuccess = TRUE;
   size_t total_len = len + 1;
   char *temp = (char*) malloc( total_len * sizeof(char) );

   fgets(temp, total_len, stdin);

   /* if the whole line wasn't read, we'll return FALSE but still copy temp into dest */
   if (temp[strlen(temp) - 1] != '\n')
      bSuccess = FALSE;
   else
      temp[strlen(temp) - 1] = '
#include <iostream>
#include <string>

using namespace std;

int main()
{
    cout << "Enter a file name:";

    string filepath;
    cin >> filepath;
}
'; /* overwrite the '\n' if it does infact exist */ strcpy(dest, temp); free(temp); return bSuccess; }

回答by Ayjay

#include"stdio.h"
#include"stdlib.h"
main()
{
    int i=0,j=0;
    char c,buf[100];

start:
    printf("Enter the name:");
    while ( (c=getchar()) != '\n' )
    {
            buf[i++]=c;
            buf[i]='##代码##';
    }
    if ( buf[0] == '##代码##')
    {
    printf("invalid name\n");
    goto start;
    }
    else
    printf("Your name is valid\nName = %s\n",buf);
      }                                                                                                                             

回答by Q_SaD

Use this simple code

使用这个简单的代码

##代码##