如果我不知道这个词有多长,我就无法写
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;
}
请输入长度=5的字符串
输入:你好
这是字符串:你好
动态保护区域时进入
EG
#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(*str)*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(*str)*(size+=16));
if(!str)return str;
}
}
str[len++]='\0';
return realloc(str, sizeof(*str)*len);
}
int main(void){
char *m;
printf("input string : ");
m = inputString(stdin, 10);
printf("%s\n", m);
free(m);
return 0;
}
使用当今的计算机,您可以分配非常大的字符串(数十万个字符),同时几乎不会减少计算机的 RAM 使用量。所以我不会太担心。
然而,在过去,当内存非常宝贵时,常见的做法是分块读取字符串。
fgets
从输入中读取最大数量的字符,但保持输入缓冲区的其余部分不变,因此您可以根据需要从中读取其余部分。
在这个例子中,我读取了 200 个字符的块,但是您当然可以使用您想要的任何块大小。
#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;
}
请注意,这是一个简化的示例,没有进行错误检查;在现实生活中,您必须通过验证
fgets
的返回值来确保输入正确。
还要注意,如果 readinput 例程结束,则不会浪费任何字节;该字符串具有所需的确切内存大小。
我只见过一种读取任意长字符串的“简单”方法,但我从未使用过它。我想事情是这样的:
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);
}
m
和
%
之间的s
告诉scanf()
测量字符串并为其分配内存并将字符串复制到其中,并将分配的内存的地址存储在相应的参数中。一旦你完成了它,你必须free()
它。不过,并非所有
scanf()
的实现都支持这一点。
正如其他人指出的那样,最简单的解决方案是对输入的长度设置限制。如果您仍然想使用
scanf()
那么您可以这样做:
char m[100];
scanf("%99s",&m);
请注意,
m[]
的大小必须至少比
%
和s
之间的数字大1个字节。如果输入的字符串超过 99,则剩余字符将等待由另一个调用或传递给
scanf()
的其余格式字符串读取。
通常不建议使用
scanf()
来处理用户输入。它最适用于由其他应用程序创建的基本结构化文本文件。即使如此,您也必须意识到输入的格式可能不符合您的预期,因为有人可能会干扰它以试图破坏您的程序。
getline
函数会自动分配所需大小的字符串,因此无需猜测字符串的大小。以下代码演示了用法:
#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;
}
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++]='\0';
return realloc(str, sizeof(char) * len);
}
fgets()
直接读入分配的空间。
需要特别注意区分读取成功、文件结束、输入错误和内存不足。 EOF 需要适当的内存管理。
此方法保留一行的
'\n'
。
#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;
}
使用示例
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;
}
getchar()
函数:-
#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]= '\0';
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);
}
这是该程序的示例运行:-
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
char *fgets (char *str, int size, FILE* file);
否则,您也可以使用动态提供请求的内存的
malloc()
函数在运行时分配内存。
#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++]='\0';
printf("%s\n",str);
free(str);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char* string;
typedef struct stringClass {
char ch;
struct stringClass *next;
}stringClass;
void get_str(char **str) {
char ch, *buffer, a;
stringClass *new = NULL;
stringClass *head = NULL, *tmp = NULL;
int c = 0, k = 0;
while ((ch = getchar()) != '\n') {
new = malloc(sizeof(stringClass));
if(new == NULL) {
return NULL;
}
new->ch = ch;
new->next = NULL;
new->next = head;
head = new;
}
tmp = head;
while (tmp != NULL) {
c++;
tmp = tmp->next;
}
if(c == 0) {
*str = "";
} else {
buffer = malloc(sizeof(char) * (c + 1));
*str = malloc(sizeof(char) * (c + 1));
if(buffer == NULL || *str == NULL) {
return NULL;
}
tmp = head;
while (tmp != NULL) {
buffer[k] = tmp->ch;
k++;
tmp = tmp->next;
}
buffer[k] = '\0';
for (int i = 0, j = strlen(buffer)-1; i < j; i++, j--) {
a = buffer[i];
buffer[i] = buffer[j];
buffer[j] = a;
}
strcpy(*str, buffer);
// Dealloc
free(buffer);
while (head != NULL) {
tmp = head;
head = head->next;
free(tmp);
}
}
}
int main() {
string str;
printf("Enter text: ");
get_str(&str);
printf("%s\n", str);
return 0;
}