programing

사용자가 C에 입력한 문자열을 읽으려면 어떻게 해야 하나요?

randomtip 2022. 7. 11. 22:47
반응형

사용자가 C에 입력한 문자열을 읽으려면 어떻게 해야 하나요?

사용자가 C 프로그램을 사용하여 입력한 이름을 읽고 싶습니다.

이에 대해 나는 다음과 같이 썼다.

char name[20];

printf("Enter name: ");
gets(name);

단, 을 사용하여gets그럼 더 좋은 방법은 무엇일까요?

사용해서는 안 됩니다.gets(또는scanf버퍼 오버플로우가 발생할 수 있기 때문입니다.를 사용합니다.fgets와 함께stdin버퍼에 저장되는 데이터를 제한할 수 있습니다.

다음은 사용자의 회선 입력에 사용하는 작은 스니펫입니다.

#include <stdio.h>
#include <string.h>

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

이것에 의해, 최대 사이즈를 설정할 수 있어 회선에 너무 많은 데이터가 입력되고 있는 것을 검출할 수 있습니다.또, 회선의 나머지 부분도 플래시 되어, 다음의 입력 조작에 영향을 주지 않습니다.

다음과 같은 방법으로 테스트할 수 있습니다.

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        // Extra NL since my system doesn't output that on EOF.
        printf ("\nNo input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long [%s]\n", buff);
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}

사용자가 입력한 문자열을 읽는 가장 안전한 방법은

다음은 그 방법의 예를 제시하겠습니다.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    char *buffer = NULL;
    int read;
    unsigned int len;
    read = getline(&buffer, &len, stdin);
    if (-1 != read)
        puts(buffer);
    else
        printf("No line read...\n");

    printf("Size read: %d\n Len: %d\n", read, len);
    free(buffer);
    return 0;
}

쉽고 좋은 해결책을 찾았습니다.

char*string_acquire(char*s,int size,FILE*stream){
    int i;
    fgets(s,size,stream);
    i=strlen(s)-1;
    if(s[i]!='\n') while(getchar()!='\n');
    if(s[i]=='\n') s[i]='\0';
    return s;
}

fget을 기반으로 하지만 '\n' 및 stdin 추가 문자가 없습니다(ffflush(stdin) 대체는 모든 OS에서 동작하지 않습니다.이 후에 문자열을 취득해야 하는 경우에 편리합니다).

POSIX 시스템에서는 가능하면 사용하는 것이 좋습니다.

Chuck Falconer의 퍼블릭 도메인을 사용할 수도 있습니다.ggets보다 가까운 구문을 제공하는 함수gets하지만 문제는 없습니다.(Chuck Falconer의 웹사이트는 더 이상 이용할 수 없습니다.archive.org는 복사본을 가지고 있고, 저는 ggets를 위한페이지를 만들었습니다.)

BSD 시스템 및 Android에서는fgetln:

#include <stdio.h>

char *
fgetln(FILE *stream, size_t *len);

다음과 같은 경우:

size_t line_len;
const char *line = fgetln(stdin, &line_len);

linenull로 종료되지 않고 다음을 포함합니다.\n(또는 사용 중인 플랫폼이 무엇이든) 최종적으로는,스트림에서 다음 I/O 작업을 수행한 후에는 유효하지 않게 됩니다.반환된 항목을 수정할 수 있습니다.line버퍼링합니다.

scanf 함수를 사용하여 문자열을 읽을 수 있습니다.

scanf("%[^\n]",name);

스트링을 받을 수 있는 더 좋은 방법은 모르겠지만

사용.scanf문자열을 입력하기 전에 공백을 제거하고 읽을 문자 수를 제한합니다.

#define SIZE 100

....

char str[SIZE];

scanf(" %99[^\n]", str);

/* Or even you can do it like this */

scanf(" %99[a-zA-Z0-9 ]", str);

읽을 수 있는 글자 수를 제한하지 않는 경우scanf만큼이나 위험할 수 있다gets

언급URL : https://stackoverflow.com/questions/4023895/how-do-i-read-a-string-entered-by-the-user-in-c

반응형