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

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

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

基本上我需要显示这个:

Enter a file name: apple.text 

基本上我需要询问用户文件名。 所以我需要一些能够获得用户输入的单词的东西。

最简单的“正确”方式可能就是这个,取自Bjarne Stroustrup的论文“ 学习标准C ++作为新语言” 。

(注意:我更改了Bjarne的代码以检查isspace()而不仅仅是行尾。另外,由于@ matejkramny的注释,使用while(1)而不是while(true) …只要我们是由于足以编辑Stroustrup的代码,我已经用C89注释而不是C ++风格了。:-P)

 #include  #include  #include  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的文件,这可能是他们关心的。

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

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

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

 #include  int main(void) { char str[BUFSIZ]; printf("Enter a file name: "); scanf("%s", str); printf("You entered: %s\n", str); } 

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

 #include  #include  #include  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; } 
 #include  int main(void) { char file[100]; printf("File Name?: \n"); fgets(file, 100, stdin); printf("Your input: %s", file); } 
 #include  #include  using namespace std; int main() { cout << "Enter a file name:"; string filepath; cin >> filepath; } 

你应该编写自己的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; } 

使用这个简单的代码

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