ENCRYPT 질문이 있읍니다.

  • ethon
    ethon

    ENCRYPT 문제에 관해 질문이 있읍니다.

    문자열 입력받을 때 fgets()로 받으면 자꾸 오답이 나고
    scanf()로 받으면 정답이 됩니다.

    즉,

    char line[100+1];
    memset(line, 0x00, 101);
    fgets(line, (sizeof(line)/sizeof(char) - 1), stdin);
    line[strlen(line) - 1] = '\0';
    

    이렇게 하면 오답으로 처리되고,

    char line[100+1];
    memset(line, 0x00, 101);
    scanf("%s", line);
    

    이렇게 하면 정답으로 통과합니다.

    fgets() 사용하는데 있어 문제가 될 만한게 있으면
    알려주시면 감사하겠읍닉다.


    10년 전
3개의 댓글이 있습니다.
  • JongMan
    JongMan

    가장 흔한 문제는 다음과 같습니다: 다음 입력이 있다고 가정해 봅시다.

    2
    hello
    world

    그런데 각 줄에는 줄의 끝을 나타내는 문자 (리눅스에서는 0x10)가 들어 있기 때문에, 파일에는 실제 다음과 같은 값들이 들어있습니다.

    2(0x10)
    hello(0x10)
    world(0x10)

    이 때 scanf("%d", ..) 로 케이스 개수를 읽어들이면, scanf는 숫자가 아닌 문자(0x10)를 만나는 시점에서 종료합니다. 이 시점에서 계속 파일을 읽어들이면 그 다음에 바로 만나는 문자가 (0x10)이니, 빈 문자열이 반환되게 됩니다.

    따라서 이 문제를 해결하기 위해서는 scanf()이후에 fgets()를 한번 더 해서 개행 문자를 읽어들여 없애는 과정이 필요합니다.


    10년 전 link
  • ethon
    ethon

    답변감사합니다.
    처음에 케이스 갯수를 읽어 들이는 부분은
    scanf("%d", &cases);
    while (getchar() != '\n');
    로 개행문자 포함 input buffer를 모두 clear한 상태입니다.
    문의하는 곳은 케이스 갯수 입력 이후에
    문자열 입력 받는 부분을 말합니다.


    10년 전 link
  • Kureyo
    Kureyo

    fgets에 대해서 찾아봤는데요
    http://en.cppreference.com/w/cpp/io/c/fgets

    예제를 보건데

    1. fgets는 항상 \0을 문자열 마지막에 포함시켜줍니다. 만약에 입력이 100인데 buf크기가 100이라면 99글자를 받고 \0을 끼워넣고 그 다음에 남은 1글자를 받습니다.
    2. fgets에서 반환하는 값은 line ending characters도 포함됩니다.

    따라서 최악의 경우 \r\n\0를 추가로 끝에 받을수 있어야되기 때문에

    char line[100+3];
    memset(line, 0x00, 103);
    fgets(line, (sizeof(line)/sizeof(char)), stdin);
    int t = sizeof(line) - 1;
    while (t >= 0 && (line[t]=='\r' || line[t]=='\n')) line[t--]='\0';
    

    이런식으로 수정하면 되지 않을까 싶습니다...


    10년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.