길이를 알 수없는 입력 문자열을 어떻게 읽을 수 있습니까?
나는 단어가 얼마나 오래 알 수없는 경우, 안 쓰기 수 char m[6];
,
단어의 길이는 긴 어쩌면 10 명 스물입니다. 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 인 문자열을 입력하십시오.
안녕하세요
이것은 문자열입니다 : hello
영역을 동적으로 확보하면서 입장
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(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++]='\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;
}
오늘날의 컴퓨터를 사용하면 컴퓨터의 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);
inputlen += templen;
input = realloc(input, inputlen+1);
strcat(input, tempbuf);
} 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[]
사이의 숫자보다 1 바이트 이상 커야합니다 .%
s
입력 한 문자열이 99보다 길면 나머지 문자는 다른 호출이나에 전달 된 나머지 형식 문자열에서 읽기를 기다립니다 scanf()
.
일반적으로 scanf()
사용자 입력 처리에는 권장되지 않습니다. 다른 응용 프로그램에서 만든 기본 구조화 된 텍스트 파일에 가장 적합합니다. 그럼에도 불구하고 누군가가 프로그램을 중단하려고 방해했을 수 있으므로 입력이 예상대로 형식화되지 않았을 수 있다는 점을 알고 있어야합니다.
더 안전한 접근 방식을 제안 할 수있는 경우 :
문자열을 담을만큼 충분히 큰 버퍼를 선언합니다.
char user_input[255];
안전한 방법으로 사용자 입력을 가져옵니다 .
fgets(user_input, 255, stdin);
입력을 얻는 안전한 방법, 첫 번째 인수는 입력이 저장 될 버퍼에 대한 포인터, 두 번째는 함수가 읽어야하는 최대 입력, 세 번째는 표준 입력에 대한 포인터입니다. 즉, 사용자 입력이 오는 위치 에서.
특히 안전은 버퍼 오버런을 방지하는 읽을 양을 제한하는 두 번째 인수에서 비롯됩니다. 또한 fgets
처리 된 문자열의 null 종료를 처리합니다.
이 기능에 대한 자세한 정보는 여기 .
편집 : 형식을 지정해야하는 경우 (예 : 문자열을 숫자로 변환) 입력이 있으면 atoi 를 사용할 수 있습니다 .
더 안전하고 빠른 (용량 배가) 버전 :
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);
}
필요한 문자열을 저장할 문자 포인터를 가져옵니다. 가능한 문자열 크기에 대해 알고 있다면 함수를 사용하십시오.
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);
}
를 사용하여 할당 된 공간을 직접 읽습니다 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;
}
4 년 만에 도착했고 너무 늦었다는 것을 알고 있지만 누군가가 사용할 수있는 다른 방법이 있다고 생각합니다. 나는 다음 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
참조 URL : https://stackoverflow.com/questions/16870485/how-can-i-read-an-input-string-of-unknown-length
'Development Tip' 카테고리의 다른 글
사용자 정의보기가있는 AlertDialog :보기의 내용을 래핑하도록 크기 조정 (0) | 2020.12.29 |
---|---|
Python에서 Jinja2의 목록을 JavaScript로 전달하는 방법 (0) | 2020.12.29 |
overflow : hidden + display : inline-block이 텍스트를 위로 이동 (0) | 2020.12.29 |
C # 동적 유형이 정적 인 이유는 무엇입니까? (0) | 2020.12.29 |
Pandas 막대 그림의 값으로 막대에 주석 달기 (0) | 2020.12.29 |