문제

사용 방법을 알아 내려고 많은 문제가 있습니다. scanf(). 정수와 잘 작동하는 것 같습니다. scanf("%d", &i).

문제가 발생하는 곳에서 사용 중입니다 scanf() 입력을 읽으려고 시도하는 루프. 예를 들어:

do {
  printf("counter: %d: ", counter);
  scanf("%c %c%d", &command, &prefix, &input);
} while (command != 'q');
  1. 내가 유효하게 구조화 된 입력과 같은 입력을 입력 할 때 c P101, 그것은 나를 홍보하기 전에 다시 반복되는 것 같습니다. 이것은 단일로도 발생하는 것 같습니다.

    scanf("%c", &c) 
    

    잠시 후. 다시 저에게 다시 프롬프하기 전에 루프를 두 번 할 것입니다. 루프를 두 번으로 만드는 것은 무엇이며 어떻게 중지합니까?

  2. 더 적은 양의 입력을 입력하면 프로그래밍 방식으로 다른 문자 나 다음과 같은 숫자가 없습니다. q, Enter를 누르면 더 많은 입력을 촉구하는 것 같습니다. 어떻게 내가 가질까 scanf() 단일 및 이중 문자 항목을 처리하기 위해?

도움이 되었습니까?

해결책

입장 할 때 "c P101"프로그램은 실제로 받는다"c P101\n". 대부분의 변환 지정자는 Newlines를 포함한 선행 공백을 건너 뜁니다. %c 하지 않습니다. 모든 것에 처음에는 "\n"읽습니다." n "주위에 두 번째는 command, "c"읽습니다 prefix, 그리고 "P"숫자가 아닌 숫자가 남아 있으므로 변환이 실패하고"P101\n"스트림에 남아 있습니다. 다음에"P"명령에 저장됩니다."1"접두사에 저장됩니다 1 (나머지에서 "01")는"로 입력에 저장됩니다. "\n"여전히 다음 번에 스트림에 있습니다. 형식 문자열의 시작 부분에 공간을두면이 문제를 해결할 수 있습니다.

두 번째 케이스에는 유사한 일이 일어나고 있습니다.q", "q\n"처음으로 하천에 들어갑니다."q"두 번째로 읽는다"\n"읽는다. 세 번째 호출에서만 두 번째 호출이다"q"읽기, 형식 문자열의 시작 부분에 공간 문자를 추가하여 문제를 다시 피할 수 있습니다.

이를 수행하는 더 좋은 방법은 fgets ()와 같은 것을 사용하여 한 번에 줄을 처리 한 다음 sscanf ()를 사용하여 구문 분석을 수행하는 것입니다.

다른 팁

정말 깨 졌어요! 나는 그것을 몰랐다

#include <stdio.h>

int main(void)
{
    int counter = 1;
    char command, prefix;
    int input;

    do 
    {
        printf("counter: %d: ", counter);
        scanf("%c %c%d", &command, &prefix, &input);
        printf("---%c %c%d---\n", command, prefix, input);
        counter++;
    } while (command != 'q');
}
counter: 1: a b1
---a b1---
counter: 2: c d2
---
 c1---
counter: 3: e f3
---d 21---
counter: 4: ---e f3---
counter: 5: g h4
---
 g3---

출력은 Robert의 답변에 맞는 것 같습니다.

라인이 포함 된 문자열이 있으면. 즉 "C P101", SSCANF의 구문 분석 능력을 사용할 수 있습니다.

보다:http://www.cplusplus.com/reference/clibrary/cstdio/sscanf.html

질문 1의 경우, 나는 당신이 당신의 printf(), " n"이 끝나지 않기 때문에.

기본 동작 printf 완전한 선이있을 때까지 출력을 버퍼하는 것입니다. 버퍼링을 명시 적으로 변경하지 않는 한입니다 stdout.

질문 2를 위해, 당신은 가장 큰 문제 중 하나를 쳤다. scanf(). 입력이 지정한 스캔 문자열과 정확히 일치하지 않는 한, 결과는 기대하는 것과 다릅니다.

옵션이 있다면 무시함으로써 더 나은 결과 (및 보안 문제가 적음)가 있습니다. scanf() 그리고 자신의 구문 분석을하고 있습니다. 예를 들어, 사용 fgets() 전체 줄을 문자열로 읽은 다음 문자열의 개별 필드를 처리하려면 sscanf().

아마도 while 루프를 사용하지 않고 ... 루프가 도움이 될 것입니다. 이런 식으로 조건은 코드를 실행하기 전에 테스트됩니다. 다음 코드 스 니펫을 시도하십시오.

 while(command != 'q')
    {
        //statements
    }

또한 문자열 길이를 미리 알고 있다면, '루프는'루프 '보다 작업하기가 훨씬 쉬울 수 있습니다. 길이를 동적으로 결정하는 몇 가지 까다로운 방법이 있습니다.

최종 분노로 : scanf() "빨리"하지 않습니다. 그것은 그것이하는 일을하고 그게 전부입니다. fgets() 입력의 검사를 기본적으로 수행하지 않기 때문에 매우 위험합니다 (위험이없는 애플리케이션에는 편리하지만). 그것은 일반적으로 이용 지점, 특히 버퍼 오버플로 공격, 해당 변수에 할당되지 않은 레지스터의 덮어 쓰기 공간으로 알려져 있습니다. 따라서 사용하기로 선택한 경우 확실한 오류 확인/수정에 시간을 보내십시오.

지금까지 처리했다고 가정하기 때문에 이것이 미래의 누군가를 도울 수 있기를 바랍니다! ;)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top