Development Tip

길이를 알 수없는 입력 문자열을 어떻게 읽을 수 있습니까?

yourdevel 2020. 12. 29. 08:03
반응형

길이를 알 수없는 입력 문자열을 어떻게 읽을 수 있습니까?


나는 단어가 얼마나 오래 알 수없는 경우, 안 쓰기 수 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

반응형