저는 입문자를 위해 C를 통해 작업하고 있습니다. 그것은 (당신이 텍스트가있는 경우, P.135) cm 인치 변환 사용에 대한 예제 코드가 gets
와 atoi
.
이제는 scanf
dreaded 대신 사용 해보고 싶었는데 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
두 번째 조각 사이 를 전환했습니다 . 둘 중 하나가 작동하도록 만들 수 있습니다. 결과가 분수 일 때 입력을 정수 값으로 제한 할 특별한 이유가 없습니다. 입력과 출력을 반향하는 것도 종종 유익합니다. 반향 된 내용이 입력 한 내용이 아니라면 무언가 끔찍하게 잘못되었다는 좋은 힌트이며 코드의 올바른 영역을 검색하도록 보냅니다.
주 : 특히에 대한 첫 번째 예에서 카펫에서 닦았 사소한의 숫자가 float
와 double
와 scanf()
와가 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);
}
다음과 같은 방법으로 많은 스택 공간을 절약 할 수 있습니다.
- 'int'는 최대 12 자이므로 입력 버퍼의 최대 길이는 13 자입니다 (NUL 문자열 종료 바이트 허용).
scanf()
12 자로 제한하십시오 . IE 'scanf( "%12s", myCharArray );
- C에서 배열의 이름은 배열의 주소로 저하되므로 'myCharArray'에 '&'가 필요하지 않습니다.
요점 3이 맞습니다. 를 char myCharArray[13];
사용 &myCharArray
하면 scanf()
et al을 호출 할 때 사용하지 않습니다 . 당신은 단지 myCharArray
. 좋은 컴파일러는 &
.
그래도 포인트 1과 2에 문제가 있습니다. 많은 문제가 지적을 피할 수 사용자 유형 다음 사용하여 라인에 9876432109876543210, 경우 scanf()
에 %12s
유효하지 않은 입력을 제거에 매우 도움이 될 수 없습니다. 행에 8 개의 읽지 않은 숫자를 남겨두고 읽은 것은 여전히 32 비트 정수를 오버플로합니다. 당신이 사용하는 경우 strtoX()
대신 긴 문자열에 대한 기능의 가족을 atoi()
, 그들은 같은 오버 플로우 등의 문제도 감지 scanf()
와 %d
도 atoi()
할 수 있습니다. (이것은 주요 답변에서 다룬 많은 요점 중 하나입니다.)
또한 메가 바이트 및 일반적으로 기가 바이트의 주 메모리가있는 시스템에서 스택의 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] 삭제
몇 마디 만하겠습니다