C语言 如何读取未知长度的输入字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16870485/
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
How can I read an input string of unknown length?
提问by coder_view
If I don't know how long the word is, I cannot write char m[6];,
The length of the word is maybe ten or twenty long.
How can I use scanfto get input from the keyboard?
如果我不知道这个词有多长,我就不会写char m[6];,
这个词的长度可能有十到二十长。如何使用scanf从键盘获取输入?
#include <stdio.h>
int main(void)
{
char m[6];
printf("please input a string with length=5\n");
scanf("%s",&m);
printf("this is the string: %s\n", m);
return 0;
}
please input a string with lenght=5
hello
this is the string: hello
请输入一个长度为 5
的字符串
hello
这是字符串:hello
回答by BLUEPIXY
Enter while securing an area dynamically
在动态确保区域的同时进入
E.G.
例如
#include <stdio.h>
#include <stdlib.h>
char *inputString(FILE* fp, size_t size){
//The size is extended by the input with the value of the provisional
char *str;
int ch;
size_t len = 0;
str = realloc(NULL, sizeof(char)*size);//size is start size
if(!str)return str;
while(EOF!=(ch=fgetc(fp)) && ch != '\n'){
str[len++]=ch;
if(len==size){
str = realloc(str, sizeof(char)*(size+=16));
if(!str)return str;
}
}
str[len++]='#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* readinput()
{
#define CHUNK 200
char* input = NULL;
char tempbuf[CHUNK];
size_t inputlen = 0, templen = 0;
do {
fgets(tempbuf, CHUNK, stdin);
templen = strlen(tempbuf);
input = realloc(input, inputlen+templen+1);
strcpy(input+inputlen, tempbuf);
inputlen += templen;
} while (templen==CHUNK-1 && tempbuf[CHUNK-2]!='\n');
return input;
}
int main()
{
char* result = readinput();
printf("And the result is [%s]\n", result);
free(result);
return 0;
}
';
return realloc(str, sizeof(char)*len);
}
int main(void){
char *m;
printf("input string : ");
m = inputString(stdin, 10);
printf("%s\n", m);
free(m);
return 0;
}
回答by Mr Lister
With the computers of today, you can get away with allocating very large strings (hundreds of thousands of characters) while hardly making a dent in the computer's RAM usage. So I wouldn't worry too much.
使用当今的计算机,您可以避免分配非常大的字符串(数十万个字符),同时几乎不会影响计算机的 RAM 使用量。所以我不会太担心。
However, in the old days, when memory was at a premium, the common practice was to read strings in chunks. fgetsreads up to a maximum number of chars from the input, but leaves the rest of the input buffer intact, so you can read the rest from it however you like.
然而,在过去,当内存非常宝贵时,通常的做法是分块读取字符串。fgets从输入中读取最多最大数量的字符,但保留输入缓冲区的其余部分不变,因此您可以随意读取其余部分。
in this example, I read in chunks of 200 chars, but you can use whatever chunk size you want of course.
在这个例子中,我读取了 200 个字符的块,但是你当然可以使用任何你想要的块大小。
char *m = NULL;
printf("please input a string\n");
scanf("%ms",&m);
if (m == NULL)
fprintf(stderr, "That string was too long!\n");
else
{
printf("this is the string %s\n",m);
/* ... any other use of m */
free(m);
}
Note that this is a simplified example with no error checking; in real life you will have to make sure the input is OK by verifying the return value of fgets.
请注意,这是一个没有错误检查的简化示例;在现实生活中,您必须通过验证 的返回值来确保输入正确fgets。
Also note that at the end if the readinput routine, no bytes are wasted; the string has the exact memory size it needs to have.
还要注意,最后如果是 readinput 例程,没有字节被浪费;该字符串具有它需要的确切内存大小。
回答by sh1
I've seen only one simpleway of reading an arbitrarily long string, but I've never used it. I think it goes like this:
我只见过一种读取任意长字符串的简单方法,但我从未使用过它。我认为它是这样的:
char m[100];
scanf("%99s",&m);
The mbetween %and stells scanf()to measure the string and allocate memory for it and copy the string into that, and to store the address of that allocated memory in the corresponding argument. Once you're done with it you have to free()it.
该m之间%并s告诉scanf()衡量字符串,并为它分配内存和字符串复制到这一点,该分配内存的地址存储在相应的参数。一旦你完成了它,你就必须free()这样做。
This isn't supported on every implementation of scanf(), though.
但是,并非每个实现都支持此功能scanf()。
As others have pointed out, the easiest solution is to set a limit on the length of the input. If you still want to use scanf()then you can do so this way:
正如其他人指出的那样,最简单的解决方案是设置输入长度的限制。如果你仍然想使用,scanf()那么你可以这样做:
char *readline(char *prompt) {
size_t size = 80;
char *str = malloc(sizeof(char) * size);
int c;
size_t len = 0;
printf("%s", prompt);
while (EOF != (c = getchar()) && c != '\r' && c != '\n') {
str[len++] = c;
if(len == size) str = realloc(str, sizeof(char) * (size *= 2));
}
str[len++]='char *fgets (char *str, int size, FILE* file);`
';
return realloc(str, sizeof(char) * len);
}
Note that the size of m[]must be at least one byte larger than the number between %and s.
注意的大小m[]必须至少一个字节比之间的数量多%和s。
If the string entered is longer than 99, then the remaining characters will wait to be read by another call or by the rest of the format string passed to scanf().
如果输入的字符串长于 99,则剩余的字符将等待被另一个调用或传递给 的格式字符串的其余部分读取scanf()。
Generally scanf()is not recommended for handling user input. It's best applied to basic structured text files that were created by another application. Even then, you must be aware that the input might not be formatted as you expect, as somebody might have interfered with it to try to break your program.
通常scanf()不推荐用于处理用户输入。它最适用于由另一个应用程序创建的基本结构化文本文件。即便如此,您也必须意识到输入的格式可能不是您所期望的,因为有人可能会干扰它以试图破坏您的程序。
回答by Nobilis
If I may suggest a safer approach:
如果我可以建议一种更安全的方法:
Declare a buffer big enough to hold the string:
声明一个足够大的缓冲区来保存字符串:
char user_input[255];
char user_input[255];
Get the user input in a safeway:
以安全的方式获取用户输入:
fgets(user_input, 255, stdin);
fgets(user_input, 255, stdin);
A safe way to get the input, the first argument being a pointer to a buffer where the input will be stored, the second the maximum input the function should read and the third is a pointer to the standard input - i.e. where the user input comes from.
获取输入的安全方法,第一个参数是指向将存储输入的缓冲区的指针,第二个是函数应该读取的最大输入,第三个是指向标准输入的指针 - 即用户输入的位置从。
Safety in particular comes from the second argument limiting how much will be read which prevents buffer overruns. Also, fgetstakes care of null-terminating the processed string.
特别是安全性来自第二个参数,限制将读取的数量,以防止缓冲区溢出。此外,还fgets负责以空字符终止处理后的字符串。
More info on that function here.
有关该功能的更多信息,请点击此处。
EDIT: If you need to do any formatting (e.g. convert a string to a number), you can use atoionce you have the input.
编辑:如果您需要进行任何格式化(例如将字符串转换为数字),您可以在输入后使用atoi。
回答by KIM Taegyoon
Safer and faster (doubling capacity) version:
更安全更快(容量翻倍)版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//I had putten the main Function Bellow this function.
//d for asking string,f is pointer to the string pointer
void GetStr(char *d,char **f)
{
printf("%s",d);
for(int i =0;1;i++)
{
if(i)//I.e if i!=0
*f = (char*)realloc((*f),i+1);
else
*f = (char*)malloc(i+1);
(*f)[i]=getchar();
if((*f)[i] == '\n')
{
(*f)[i]= 'Enter the String:- I am Using Linux Mint XFCE 18.2 , eclispe CDT and GCC7.2 compiler!!
Your String:- I am Using Linux Mint XFCE 18.2 , eclispe CDT and GCC7.2 compiler!!
And It's length:- 67
';
break;
}
}
}
int main()
{
char *s =NULL;
GetStr("Enter the String:- ",&s);
printf("Your String:- %s \nAnd It's length:- %lu\n",s,(strlen(s)));
free(s);
}
回答by Dayal rai
Take a character pointer to store required string.If you have some idea about possible size of string then use function
取一个字符指针来存储所需的字符串。如果您对字符串的可能大小有所了解,请使用函数
#include<stdio.h>
#include<malloc.h>
int main()
{
char *str,ch;
int size=10,len=0;
str=realloc(NULL,sizeof(char)*size);
if(!str)return str;
while(EOF!=scanf("%c",&ch) && ch!="\n")
{
str[len++]=ch;
if(len==size)
{
str = realloc(str,sizeof(char)*(size+=10));
if(!str)return str;
}
}
str[len++]='#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, stdin)) != -1) {
printf("Retrieved line of length %zu :\n", read);
printf("%s", line);
}
if (ferror(stdin)) {
/* handle error */
}
free(line);
return 0;
}
';
printf("%s\n",str);
free(str);
}
else you can allocate memory on runtime too using malloc()function which dynamically provides requested memory.
否则,您也可以使用动态提供请求内存的malloc()函数在运行时分配内存。
回答by Dayal rai
I know that I have arrived after 4 years and am too late but I think I have another way that someone can use. I had used getchar()Function like this:-
我知道我是在 4 年后到达的,但为时已晚,但我认为我有另一种方式可供人们使用。我曾经使用过这样的getchar()函数:-
#include <stdio.h>
#include <stdlib.h>
#define FGETS_ALLOC_N 128
char* fgets_alloc(FILE *istream) {
char* buf = NULL;
size_t size = 0;
size_t used = 0;
do {
size += FGETS_ALLOC_N;
char *buf_new = realloc(buf, size);
if (buf_new == NULL) {
// Out-of-memory
free(buf);
return NULL;
}
buf = buf_new;
if (fgets(&buf[used], (int) (size - used), istream) == NULL) {
// feof or ferror
if (used == 0 || ferror(istream)) {
free(buf);
buf = NULL;
}
return buf;
}
size_t length = strlen(&buf[used]);
if (length + 1 != size - used) break;
used += length;
} while (buf[used - 1] != '\n');
return buf;
}
here is the sample run for this program:-
这是该程序的示例运行:-
int main(void) {
FILE *istream = stdin;
char *s;
while ((s = fgets_alloc(istream)) != NULL) {
printf("'%s'", s);
free(s);
fflush(stdout);
}
if (ferror(istream)) {
puts("Input error");
} else if (feof(istream)) {
puts("End of file");
} else {
puts("Out of memory");
}
return 0;
}
回答by Priyanshu Agrawal
i also have a solution with standard inputs and outputs
我也有一个标准输入和输出的解决方案
##代码##回答by Parham Alvani
There is a new function in C standard for getting a line without specifying its size. getlinefunction allocates string with required size automatically so there is no need to guess about string's size. The following code demonstrate usage:
C 标准中有一个新函数可以在不指定大小的情况下获取一行。getline函数自动分配所需大小的字符串,因此无需猜测字符串的大小。以下代码演示了用法:
回答by chux - Reinstate Monica
Read directly into allocated space with fgets().
直接读入分配的空间fgets()。
Special care is need to distinguish a successful read, end-of-file, input error and out-of memory. Proper memory management needed on EOF.
需要特别注意区分成功读取、文件结束、输入错误和内存不足。EOF 需要适当的内存管理。
This method retains a line's '\n'.
此方法保留一行的'\n'.
Sample usage
示例用法
##代码##
