간단한 방정식에서 get을 scanf로 바꾸면 프로그램이 충돌합니다.

Ducoodi

저는 입문자를 위해 C를 통해 작업하고 있습니다. 그것은 (당신이 텍스트가있는 경우, P.135) cm 인치 변환 사용에 대한 예제 코드가 getsatoi.

이제는 scanfdreaded 대신 사용 해보고 싶었는데 gets이것이 제가 생각 해낼 수있는 최선의 방법입니다 (저자가 제공 한 코드를 기반으로 함).

#include <stdio.h>
#include <stdlib.h>

int main()
{
    float height_in_cm;
    char height_in_inches;

    printf("Enter your height in inches: ");
    scanf("%c"),&height_in_inches;
    height_in_cm = atoi(height_in_inches)*2.54;
    printf("You are %.2f centimetres tall.\n",height_in_cm);
    return(0);
}

프로그램이 시작되지만 입력 후 충돌이 발생합니다. 내가 어디로 잘못 가고 있습니까?

조나단 레플러

scanf()당신을 위해 있을 때 답을 변환하는데 시간을 할애 합니까?

#include <stdio.h>

int main(void)
{
    float height_in_inches;

    printf("Enter your height in inches: ");
    if (scanf("%f", &height_in_inches) == 1)
    {
        float height_in_cm = height_in_inches * 2.54;
        printf("You are %.2f inches or %.2f centimetres tall.\n",
               height_in_inches, height_in_cm);
    }
    else
        printf("I didn't understand what you said\n");
    return(0);
}

문자열을 읽어야하는 경우 다음을 사용하십시오 fgets().

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char line[4096];

    printf("Enter your height in inches: ");
    if (fgets(line, sizeof(line), stdin) != 0)
    {
        double height_in = strtod(line, 0);
        double height_cm = height_in * 2.54;
        printf("You are %.2f inches or %.2f centimetres tall.\n",
               height_in, height_cm);
    }
    return(0);
}

두 프로그램 모두 입력 결과를 사용하기 전에 입력이 발생했는지 확인합니다. 호출에 대한 오류 검사 strtod()가 매우 부족 하다고 주장 할 수 있습니다 . 동의합니다. float첫 번째 조각과 double번째 조각 사이 전환했습니다 . 둘 중 하나가 작동하도록 만들 수 있습니다. 결과가 분수 일 때 입력을 정수 값으로 제한 할 특별한 이유가 없습니다. 입력과 출력을 반향하는 것도 종종 유익합니다. 반향 된 내용이 입력 한 내용이 아니라면 무언가 끔찍하게 잘못되었다는 좋은 힌트이며 코드의 올바른 영역을 검색하도록 보냅니다.

주 : 특히에 대한 첫 번째 예에서 카펫에서 닦았 사소한의 숫자가 floatdoublescanf()와가 printf(). 아래 설명을 감안할 때 현재 OP와 관련이 없습니다.

원본 코드에 대한 최소한의 수정

위의 코드는 OP가 아직 인식하는 것보다 더 복잡하기 때문에 여기에 원본 코드에 대한 더 간단한 수정 세트가 있습니다. 배열 (문자열)에 입력 된 문자열이 핵심입니다. scanf()전화도 변경이 필요했습니다 . 큰 버퍼를 사용하면 사용자가 터미널에 입력하여 입력을 오버플로 할 수 없다고 가정 할 수 있습니다. 그러나 기계 구동 입력에는 적합하지 않습니다.

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    float height_in_cm;
    char height_in_inches[4096];    // Array, big enough to avoid most overflows

    printf("Enter your height in inches: ");
    // Missing error check on scanf() — too advanced as yet
    scanf("%s", height_in_inches);  // Format specifier, parentheses, ampersand
    height_in_cm = atoi(height_in_inches) * 2.54;
    printf("You are %s inches or %.2f centimetres tall.\n",
           height_in_inches, height_in_cm);
    return(0);
}

입력 한 줄은 얼마나됩니까?

user3629249 댓글 :

다음과 같은 방법으로 많은 스택 공간을 절약 할 수 있습니다.

  1. 'int'는 최대 12 자이므로 입력 버퍼의 최대 길이는 13 자입니다 (NUL 문자열 종료 바이트 허용).
  2. scanf()12 자로 제한하십시오 . IE 'scanf( "%12s", myCharArray );
  3. C에서 배열의 이름은 배열의 주소로 저하되므로 'myCharArray'에 '&'가 필요하지 않습니다.

요점 3이 맞습니다. char myCharArray[13];사용 &myCharArray하면 scanf()et al을 호출 할 때 사용하지 않습니다 . 당신은 단지 myCharArray. 좋은 컴파일러는 &.

그래도 포인트 1과 2에 문제가 있습니다. 많은 문제가 지적을 피할 수 사용자 유형 다음 사용하여 라인에 9876432109876543210, 경우 scanf()%12s유효하지 않은 입력을 제거에 매우 도움이 될 수 없습니다. 행에 8 개의 읽지 않은 숫자를 남겨두고 읽은 것은 여전히 ​​32 비트 정수를 오버플로합니다. 당신이 사용하는 경우 strtoX()대신 긴 문자열에 대한 기능의 가족을 atoi(), 그들은 같은 오버 플로우 등의 문제도 감지 scanf()%datoi()할 수 있습니다. (이것은 주요 답변에서 다룬 많은 요점 중 하나입니다.)

또한 메가 바이트 및 일반적으로 기가 바이트의 주 메모리가있는 시스템에서 스택의 4KiB는 큰 문제가 아닙니다. 즉, 충격 값에 부분적으로 4KiB를 사용합니다. 하지만 POSIX는 2048의 [LINE_MAX] 최소값이 필요합니다.

일반적으로 명령 줄 응용 프로그램에서 입력을 수행하는 좋은 방법 인 줄 기반 입력을 읽는 경우 부분 줄을 사용하는 것이 지저분하고 오류보고를 어렵게 만들기 때문에 전체 줄을 읽도록해야합니다. fgets()플러스 sscanf()처리 의 한 가지 주요 이점은 라인의 scanf()일부를 처리 한 후 남은 것이 아니라 오류 보고서에서 사용할 수있는 완전한 라인이 있다는 것 입니다. 첫 번째 시도가 실패하면 다른 방법으로 문자열을 스캔 해 볼 수도 있습니다. scanf()패밀리 의 직접 파일 I / O 기능으로는이를 수행 할 수 없습니다 .

사람들이 짧은 줄을 입력하려고 할 때 긴 줄을 입력하는 것을 순진하게 인식하지 못한다면, 이전 입력 줄의 찌꺼기 일 때 추가 사용자 상호 작용없이 남은 음식을 새 줄로 제공 할 수 있습니다. 예를 들어 20 개 중 12 자리를 스캔하면 추가 입력을 요청하더라도 사용자가 새로운 것을 입력 할 때까지 기다리지 않고 나머지 8 자리를 다음 입력에 가져옵니다. (또한, 조심 하여fflush(stdin) , 그것은 아무것도 유용하지 여부를 최적의 시스템 별이다.)

I 사용 fgets()4 킬로바이트 완충액. 한 줄에 메가 바이트의 JSON 인코딩 데이터를 보내는 프로그램에 대해 안전을 유지하려면 POSIX의 getline()기능을 사용 하여 줄을 읽어야합니다. 메모리가 부족하지 않는 한 전체 라인에 충분한 공간을 할당합니다. 대부분의 학생 연습 작업의 경우 4KiB 버퍼이며 fgets()합리적인 대리입니다. 지수가 8 이상인 한 사용 된 2의 거듭 제곱에 대해 협상 할 의향이 있습니다. 값이 256 이상입니다. 예를 들어, 라인 버퍼를 80 자로 제한한다고해서 사용자가 다음 값 이상을 입력하는 것을 막을 수는 없습니다. 한 줄에 80 자. 추가 문자가 적절하게 처리되지 않을 가능성이 있음을 의미합니다. 버퍼를 13 자로 제한하는 것은 가치있는 것을 사지 못합니다. IMO와 '스택 공간 절약'은 조기 최적화입니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

내 방정식 풀기 프로그램에서 nil 값을 입력하면 앱이 충돌합니다.

분류에서Dev

arraylist에 막대한 양의 비트 맵을로드하면 내 응용 프로그램이 충돌합니다.

분류에서Dev

특정 태블릿에서 사진을 찍으면 응용 프로그램이 충돌합니다

분류에서Dev

for 루프에서 2D 배열을 인쇄하면 프로그램이 충돌합니다.

분류에서Dev

목록보기에서 선택한 항목을 변경하려고하면 프로그램이 충돌합니다.

분류에서Dev

프로그램이 중간에 충돌합니다. 이유를 모릅니다.

분류에서Dev

DataPoint 배열에 값을 추가하면 실행 중 응용 프로그램 충돌이 발생합니다.

분류에서Dev

2D 배열 값을 늘리면 프로그램이 충돌합니다.

분류에서Dev

MPI_Wait가 간단한 프로그램을 충돌시킵니다.

분류에서Dev

.removeStateDidListener를 deinit에 추가하면 응용 프로그램이 충돌합니다.

분류에서Dev

활동에서 브로드 캐스트 수신기로 값을 전달하려고하면 응용 프로그램이 충돌합니다.

분류에서Dev

간단한 웹 자바 앱은 heroku 로컬 웹에서 작동하지만 배포시 충돌합니다.

분류에서Dev

Android 앱에서 글꼴을 변경하면 응용 프로그램이 충돌합니다. 기본 서체를 만들 수 없습니다.

분류에서Dev

TCP / IP 연결을 종료 한 후 POSIX "쓰기"기능을 사용하면 응용 프로그램이 충돌합니다. 이유는 무엇입니까?

분류에서Dev

while 루프에서 조건 순서를 변경하면 프로그램이 충돌합니다.

분류에서Dev

다른 프로그램 내에서 의도적으로 충돌하는 프로그램을 실행 한 다음 원래 프로세스로 돌아갑니다.

분류에서Dev

SetContentView가 기본 활동으로 다시 설정되면 응용 프로그램이 충돌합니다.

분류에서Dev

카운터가 루프 내에서 사용되면 C ++ 프로그램이 충돌합니다.

분류에서Dev

extern DLL을 사용하여 네트워크 공유에서 .NET 응용 프로그램을 시작하면 충돌이 발생합니다.

분류에서Dev

DBD / DBI : 프로그램이 분기되면 충돌합니다.

분류에서Dev

countdowntimer가 완료되기 전에 조각을 변경하면 응용 프로그램이 Android에서 충돌합니다.

분류에서Dev

Windows에서 간단한 C 프로그램 충돌

분류에서Dev

"연결 프로그램"을 사용하면 C # WPF 앱이 자동으로 충돌합니다.

분류에서Dev

변수 filename으로 파일을 열려고하면 c 프로그램이 충돌합니다.

분류에서Dev

활동에 버튼을 놓으면 Android 응용 프로그램이 충돌하고 빈 활동이 작동합니다.

분류에서Dev

다른 프로그램이 닫힐 때 한 프로그램을 자동으로 닫는 (간단한) 방법이 있습니까?

분류에서Dev

그리드에 여러 캔버스를 삽입하면 프로그램이 충돌합니다.

분류에서Dev

델파이에서 LdrLoadDll을 연결할 때 응용 프로그램이 충돌합니다.

분류에서Dev

동일한 리그의 충돌체가 서로 충돌하는 것을 방지합니다. 그러나 다른 리그와 충돌 할 수 있습니다.

Related 관련 기사

  1. 1

    내 방정식 풀기 프로그램에서 nil 값을 입력하면 앱이 충돌합니다.

  2. 2

    arraylist에 막대한 양의 비트 맵을로드하면 내 응용 프로그램이 충돌합니다.

  3. 3

    특정 태블릿에서 사진을 찍으면 응용 프로그램이 충돌합니다

  4. 4

    for 루프에서 2D 배열을 인쇄하면 프로그램이 충돌합니다.

  5. 5

    목록보기에서 선택한 항목을 변경하려고하면 프로그램이 충돌합니다.

  6. 6

    프로그램이 중간에 충돌합니다. 이유를 모릅니다.

  7. 7

    DataPoint 배열에 값을 추가하면 실행 중 응용 프로그램 충돌이 발생합니다.

  8. 8

    2D 배열 값을 늘리면 프로그램이 충돌합니다.

  9. 9

    MPI_Wait가 간단한 프로그램을 충돌시킵니다.

  10. 10

    .removeStateDidListener를 deinit에 추가하면 응용 프로그램이 충돌합니다.

  11. 11

    활동에서 브로드 캐스트 수신기로 값을 전달하려고하면 응용 프로그램이 충돌합니다.

  12. 12

    간단한 웹 자바 앱은 heroku 로컬 웹에서 작동하지만 배포시 충돌합니다.

  13. 13

    Android 앱에서 글꼴을 변경하면 응용 프로그램이 충돌합니다. 기본 서체를 만들 수 없습니다.

  14. 14

    TCP / IP 연결을 종료 한 후 POSIX "쓰기"기능을 사용하면 응용 프로그램이 충돌합니다. 이유는 무엇입니까?

  15. 15

    while 루프에서 조건 순서를 변경하면 프로그램이 충돌합니다.

  16. 16

    다른 프로그램 내에서 의도적으로 충돌하는 프로그램을 실행 한 다음 원래 프로세스로 돌아갑니다.

  17. 17

    SetContentView가 기본 활동으로 다시 설정되면 응용 프로그램이 충돌합니다.

  18. 18

    카운터가 루프 내에서 사용되면 C ++ 프로그램이 충돌합니다.

  19. 19

    extern DLL을 사용하여 네트워크 공유에서 .NET 응용 프로그램을 시작하면 충돌이 발생합니다.

  20. 20

    DBD / DBI : 프로그램이 분기되면 충돌합니다.

  21. 21

    countdowntimer가 완료되기 전에 조각을 변경하면 응용 프로그램이 Android에서 충돌합니다.

  22. 22

    Windows에서 간단한 C 프로그램 충돌

  23. 23

    "연결 프로그램"을 사용하면 C # WPF 앱이 자동으로 충돌합니다.

  24. 24

    변수 filename으로 파일을 열려고하면 c 프로그램이 충돌합니다.

  25. 25

    활동에 버튼을 놓으면 Android 응용 프로그램이 충돌하고 빈 활동이 작동합니다.

  26. 26

    다른 프로그램이 닫힐 때 한 프로그램을 자동으로 닫는 (간단한) 방법이 있습니까?

  27. 27

    그리드에 여러 캔버스를 삽입하면 프로그램이 충돌합니다.

  28. 28

    델파이에서 LdrLoadDll을 연결할 때 응용 프로그램이 충돌합니다.

  29. 29

    동일한 리그의 충돌체가 서로 충돌하는 것을 방지합니다. 그러나 다른 리그와 충돌 할 수 있습니다.

뜨겁다태그

보관