似乎有很多种方法可以在C语言中获取用户输入。
哪种方式是需要很少代码的最简单的方法?
基本上我需要显示这个:
Enter a file name: apple.text
基本上,我需要向用户询问一个文件名。因此,我需要一个只获取用户输入的那个词的东西。
从Bjarne Stroustrup的《作为新语言学习标准C ++》一文中,最简单而“正确”的方法可能是下面这个。
(注:我更改了Bjarne的代码以检查isspace()
而不仅仅是行末。另外,由于@matejkramny的评论,使用while(1)
而不是while(true)
...并且只要我们足够异端,编辑Stroustrup的代码,我也替换了C++风格的注释为C89风格的。:-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-like"的东西,那么考虑转向C++绝对是值得的。它被设计用于处理这些问题--使用可靠且可扩展的技术,同时仍然具有良好的性能。
while(true)
,我的编译器抱怨了。不过现在我明白了,谢谢 :) - Matejscanf
在非敌对环境下运作良好。换句话说,你正在为自己制作一个简单的实用程序。
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;
}
#include <stdio.h>
int main(void)
{
char file[100];
printf("File Name?: \n");
fgets(file, 100, stdin);
printf("Your input: %s", file);
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Enter a file name:";
string filepath;
cin >> filepath;
}
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;
}
scanf
有字符限制,例如 scanf("%99s", mySize100Buffer);
。但是,与 fgets
不同,边界由数字字符串指定,因此捕获 BUFSIZE-1 关系需要生成自定义格式字符串。有点不切实际... - HostileFork says dont trust SE#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);
}