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

时间:2011-10-20 06:05:39

标签: c input io scanf

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

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

基本上我需要显示:

Enter a file name: apple.text

基本上我需要询问用户文件名。所以我需要的东西只能得到用户输入的那个词。

6 个答案:

答案 0 :(得分:23)

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

(注意:我更改了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;
}

包括:

  • 跳过空格,直到找到字符输入
  • 动态扩展字符串缓冲区以适应任意大小的字符串
  • 处理无法分配内存的条件

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

如果将scanf用于缓冲区而不限制读取大小,则输入超出缓冲区大小,会产生安全漏洞和/或崩溃。

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

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

答案 1 :(得分:7)

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

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

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:1)

#include <iostream>
#include <string>

using namespace std;

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

    string filepath;
    cin >> filepath;
}

答案 4 :(得分:1)

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

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

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] = '\0'; /* overwrite the '\n' if it does infact exist */

   strcpy(dest, temp);

   free(temp);
   return bSuccess;
}

答案 5 :(得分:0)

使用这个简单的代码

#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]='\0';
    }
    if ( buf[0] == '\0')
    {
    printf("invalid name\n");
    goto start;
    }
    else
    printf("Your name is valid\nName = %s\n",buf);
      }