问题如下:
我想从标准输入中输入一行,但我不知道它的大小,可能非常长。
像 scanf
,gets
这样的方法需要知道您可能输入的最大长度,以便您的输入大小小于缓冲区大小。
那么有没有好的方法来处理它呢?
答案必须只用 C 语言,不能用 C++,因此 C++ 字符串不是我想要的。我想要的是 C 标准字符串,类似于 char*
并以 '\0'
结尾。
C标准没有定义这样的函数,但是POSIX有。
getline
函数可以实现你所需的功能,文档在此(如果你使用的是类UNIX系统,可以输入man getline
查看)。
它可能在非POSIX系统(如MS Windows)上不可用。
下面是一个演示其用法的小程序:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *line = NULL;
size_t n = 0;
ssize_t result = getline(&line, &n, stdin);
printf("result = %zd, n = %zu, line = \"%s\"\n", result, n, line);
free(line);
}
fgets
类似,'\n'
换行符会留在数组中。一种方法是使用getchar
运行循环,并将字符放入数组中。一旦数组已满,使用realloc
来增大它的大小。
C
语言,你需要自己完成所有的工作并创建库。 - Bhargav Raogetch()
函数。你可能想用的是getc()
或者getchar()
? - alk#include<stdio.h>
#include<stdlib.h>
void main(){
int size = 10;
char* str;
str = (char*) calloc(size,sizeof(char));
char c;
c = getchar();
int t = 0;
int cnt = 0;
int len;
while(c!='\n') {
if(cnt > size) {
str = (char*) realloc(str,2*cnt);
}
str[t] = c;
c = getchar();
t++;
cnt++;
}
str[t]='\0';
printf("The string is %s\n",str);
len = strlen(str);
printf("The size is %d",len);
}
在scanf
中经常被忽视的一个转换说明符
可以分配足够长的内存来保存字符串输入,而不受长度限制。较新版本的scanf
使用m
来实现此目的。 早期版本使用a
。例如:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *str = NULL;
printf (" enter a string of any length, whitespace is OK: ");
scanf ("%m[^\n]%*c", &str);
printf ("\n str: %s\n\n", str);
if (str) free (str);
return 0;
}
注意:scanf
需要一个char **
指针参数来接收分配的字符串。此外,请注意,scanf不会在存储的字符串中包含'\n'
。进一步注意%*c
,它接收并丢弃'\n'
字符,以防止换行符留在输入缓冲区中。您还可以在转换说明符之前加上空格,以跳过可能存在于输入缓冲区中的任何/所有空格。
最后注意:有报告称,并非所有的scanf
实现都提供此功能。(这也可能是m/a
更改的混淆)请检查您的实现。
'm'
的使用是由 POSIX 定义的,但不是由 ISO C 定义的。 - Keith Thompson'm'
之前是 'a'
,所以你必须查看你的 scanf
版本的 man page -- 很好的观点。 - David C. Rankinm
修饰符的支持存疑。 - David C. Rankinmalloc
为缓冲区分配存储空间,并跟踪您添加的字符数,当达到分配的限制时,使用realloc
将缓冲区大小加倍并继续添加。 - David C. Rankin使用 getchar
、malloc
和 realloc
读取无限输入字符串。
声明 String 类型,也可以使用 char *
。
// String type
typedef char *String;
/**
* Join the Char into end of String
*
* @param string - String
* @param c - joined char
*/
void String_joinChar(String *string, const char c)
{
const size_t length = strlen(*string);
(*string) = (String)realloc((*string), sizeof(char) * (length + 2));
(*string)[length] = c;
(*string)[length + 1] = '\0';
}
这个函数用于输入字符串,它通过使用getchar
从键盘读取字符,并将其连接到当前字符串的末尾。
/**
* Input String
*
* @return Inputed String
*/
String String_input()
{
String string = (String)malloc(sizeof(char));
strcpy(string, "");
char cursor;
fflush(stdin);
while ((cursor = getchar()) != '\n' && cursor != EOF)
{
String_joinChar(&string, cursor);
}
return string;
}
char *
、malloc
和realloc
,我们必须释放它。/**
* Destroy String
*
* @param string - Destroyed String
*/
void String_destroy(String string)
{
free(string);
}
现在我们只需要使用它!!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
String string = String_input();
printf("\n%s\n", string);
String_destroy(string);
return 0;
}
希望对你有用!
fgets(user_name, 1000, stdin)
就足够了。 - chux - Reinstate Monicagets
不允许您指定目标数组的大小。这就是它固有的不安全性所在,这也是为什么它在2011年ISO C标准中被移除的原因。您是不是想使用fgets
? - Keith Thompson