programing

문자열에 메모리 공간을 동적으로 할당하고 사용자로부터 해당 문자열을 가져오려면 어떻게 해야 합니까?

randomtip 2022. 7. 16. 15:24
반응형

문자열에 메모리 공간을 동적으로 할당하고 사용자로부터 해당 문자열을 가져오려면 어떻게 해야 합니까?

C 프로그램을 사용하여 사용자의 입력을 읽고 싶습니다.어레이를 사용하고 싶지 않습니다.

char names[50];

사용자가 길이 10의 문자열을 지정하면 나머지 공간이 낭비되기 때문입니다.

이렇게 포인터를 쓰면

char *names;

그런 식으로 메모리를 할당해야 합니다.

names = (char *)malloc(20 * sizeof(char));

이 경우에도 메모리 낭비 가능성이 있습니다.

따라서 문자열의 길이와 정확히 같은 길이의 문자열을 위해 메모리를 동적으로 할당해야 합니다.

예를 들어,

사용자 입력이"stackoverflow"할당된 메모리는 다음과 같습니다.14(예: 문자열의 길이 = 13 및 '\0'에 대한 추가 공간 1).

어떻게 하면 이런 일을 할 수 있을까요?

한 번에 한 글자씩 읽기(사용)getc(stdin)스트링을 확장합니다( ).realloc)을 클릭합니다.

여기 제가 얼마 전에 쓴 함수가 있습니다.텍스트 입력 전용입니다.

char *getln()
{
    char *line = NULL, *tmp = NULL;
    size_t size = 0, index = 0;
    int ch = EOF;

    while (ch) {
        ch = getc(stdin);

        /* Check if we need to stop. */
        if (ch == EOF || ch == '\n')
            ch = 0;

        /* Check if we need to expand. */
        if (size <= index) {
            size += CHUNK;
            tmp = realloc(line, size);
            if (!tmp) {
                free(line);
                line = NULL;
                break;
            }
            line = tmp;
        }

        /* Actually store the thing. */
        line[index++] = ch;
    }

    return line;
}

만약 당신이 기억을 남겨야 한다면, 한 자씩 읽고 매번 재할당하세요.퍼포먼스는 저하되지만 이 10바이트를 절약할 수 있습니다.

또 하나의 좋은 단점은 함수를 읽은 후(로컬 변수를 사용하여) 복사하는 것입니다.따라서 큰 버퍼는 함수 범위가 지정됩니다.

정규 표현을 사용할 수도 있습니다.예를 들어 다음과 같은 코드도 사용할 수 있습니다.

char *names
scanf("%m[^\n]", &names)

는 stdin에서 전체 행을 가져와 필요한 공간을 동적으로 할당합니다.물론 그 후에는 자유로워져야 합니다names.

10개의 요소로 시작하는 배열이 있을 수 있습니다.입력 내용을 한 글자씩 읽습니다.문제가 해결되면 5개를 더 할당합니다.최선은 아니지만, 다른 공간은 나중에 비워도 돼요.

다이내믹 스트링을 작성하기 위한 코드를 다음에 나타냅니다.

void main()
{
  char *str, c;
  int i = 0, j = 1;

  str = (char*)malloc(sizeof(char));

  printf("Enter String : ");

  while (c != '\n') {
    // read the input from keyboard standard input
    c = getc(stdin);

    // re-allocate (resize) memory for character read to be stored
    str = (char*)realloc(str, j * sizeof(char));

    // store read character by making pointer point to c
    str[i] = c;

    i++;
    j++;
  }

  str[i] = '\0'; // at the end append null character to mark end of string

  printf("\nThe entered string is : %s", str);

  free(str); // important step the pointer declared must be made free
}

재할당은 비용이 많이 드는 작업입니다.문자열을 수신하는 방법은 다음과 같습니다.재할당 비율은 1:1이 아닙니다.

char* getAString()
{    
    //define two indexes, one for logical size, other for physical
    int logSize = 0, phySize = 1;  
    char *res, c;

    res = (char *)malloc(sizeof(char));

    //get a char from user, first time outside the loop
    c = getchar();

    //define the condition to stop receiving data
    while(c != '\n')
    {
        if(logSize == phySize)
        {
            phySize *= 2;
            res = (char *)realloc(res, sizeof(char) * phySize);
        }
        res[logSize++] = c;
        c = getchar();
    }
    //here we diminish string to actual logical size, plus one for \0
    res = (char *)realloc(res, sizeof(char *) * (logSize + 1));
    res[logSize] = '\0';
    return res;
}
char* load_string()
 {

char* string = (char*) malloc(sizeof(char));
*string = '\0';

int key;
int sizer = 2;

char sup[2] = {'\0'};

while( (key = getc(stdin)) != '\n')
{
    string = realloc(string,sizer * sizeof(char));
    sup[0] = (char) key;
    strcat(string,sup);
    sizer++

}
return string;

}

int main()
  {
char* str;
str = load_string();

return 0;
  }

먼저 입력의 구조에 따라 입력을 읽기 위한 새로운 함수를 정의하고 스트링을 저장합니다.이 문자열은 사용되는 스택 내의 메모리를 의미합니다.입력에 충분한 문자열 길이를 설정합니다.

둘째, 사용strlen이전에 저장된 문자열의 정확한 사용 길이를 측정합니다.malloc힙에 메모리를 할당하다.그 길이는 에 의해 정의된다.strlen코드는 다음과 같습니다.

int strLength = strlen(strInStack);
if (strLength == 0) {
    printf("\"strInStack\" is empty.\n");
}
else {
    char *strInHeap = (char *)malloc((strLength+1) * sizeof(char));
    strcpy(strInHeap, strInStack);
}
return strInHeap;

이 .strInStack로로 합니다.strInHeap를 사용합니다.strcpystrInHeap . 。strInStack이 하위 기능에서만 종료되므로 자동으로 해방됩니다.

이것은 사용자 입력을 스캔하여 사용자 입력과 동일한 크기의 배열에 저장하기 위해 작성한 함수 스니펫입니다."\0" 문자를 저장할 수 있도록 j를 2의 값으로 초기화합니다.

char* dynamicstring() {
    char *str = NULL;
    int i = 0, j = 2, c;
    str = (char*)malloc(sizeof(char));
    //error checking
    if (str == NULL) {
        printf("Error allocating memory\n");
        exit(EXIT_FAILURE);
    }

    while((c = getc(stdin)) && c != '\n')
    {
        str[i] = c;
        str = realloc(str,j*sizeof(char));
        //error checking
        if (str == NULL) {
            printf("Error allocating memory\n");
            free(str);
            exit(EXIT_FAILURE);
        }

        i++;
        j++;
    }
    str[i] = '\0';
    return str;
}

main()에서는 다른 char* 변수를 선언하여 dynamicstring()의 반환값을 저장한 후 사용이 끝나면 해당 char* 변수를 해제할 수 있습니다.

여기 같은 기능을 수행하는 스니펫이 있습니다.

이 코드는 Kunal Wadhwa가 작성한 코드와 유사합니다.

char *dynamicCharString()
{
    char *str, c;
    int i = 0;
    str = (char*)malloc(1*sizeof(char));

    while(c = getc(stdin),c!='\n')
    {
      str[i] = c;
      i++;
      realloc(str,i*sizeof(char));
    }
    str[i] = '\0';
    return str;
}

언급URL : https://stackoverflow.com/questions/8164000/how-to-dynamically-allocate-memory-space-for-a-string-and-get-that-string-from-u

반응형