2014-01-21 3 views
1

시간, 사용자 ID 및 가중치를 기록하는 앱을 만들고 있습니다. 처음 전달 된 토큰이 정수인지 어떻게 확인할 수 있습니까? 나는 isdigit을 사용할 것이라고 생각했지만, 그것은 단일 문자로만 작동합니다. 첫 번째 토큰이 정수가 아닌 경우 올바르지 않은 시간을 출력하고 싶습니다. 첫 번째 토큰은 정수 (예를 들어 알파벳을 가지고) 나는 아직도 내가 원하지 않는 변수 타임 스탬프 ,,의 수를 얻을 수없는 경우 나는 현재전달 된 문자열이 정수인지 확인합니다.

sscanf(userInput, "%d %s %f", &timestamp, userID, &weight); 

을 사용하고 있습니다.

int main() 
{ 
    char userInput[99]; 
    int timestamp, timestampT = 0; 
    char userID[31]; 
    userID[0] = 0; 
    float weight, weightT, day, rateW; 

    while(fgets(userInput, 99, stdin) != NULL){ 
     sscanf(userInput, "%d %s %f", &timestamp, userID, &weight); 

     if(timestamp == 0){ 
      printf("%s\n", "Invalid time"); 
     } 
     else if(!isalpha(userID[0]) || userID[0]=='_' || userID[0] == 0){ 
      printf("%s\n", "Illegal userID"); 
     } 
     else if(weight < 30.0 || weight > 300.0){ 
      printf("%s\n", "Illegal weight"); 
     } 
     else if(timestampT > 0){ 
      day = timestampT/86400; 
      rateW = (weightT -weight)/(day - timestamp/86400); 
      if(rateW > 10.0 || rateW < -10.0){ 
       printf("%s\n", "Suspiciously large weight change"); 
      } 

     } 
     else{ 
      printf("%d %s %f \n", timestamp, userID, weight); 
      timestampT = timestamp; 
      timestamp = 0; 
      weightT = weight; 
     } 

     userID[0] = 0; 
    } 
} 
+1

sscanf의 결과를 사용하여 다른 문자열을 작성한 다음 원본을 다시 작성 문자열과 비교하십시오. 서로 다르다면 올바르게 변환되지 않은 것입니다. 예 : 'foo = printf ('% d % s, % f', 값, 여기); if (! strcmp (foo, userinput)) {ruh_roh(); }' –

+1

['sscanf()'] (http://en.cppreference.com/w/c/io/fscanf)의 결과를 사용하여 * 성공적으로 구문 분석 된 매개 변수의 수를 확인하십시오. [여섯 번째 계명에 유의 **] – WhozCraig

+0

문자열의 모든 문자를 타임 스탬프의 경우 'isdigit'로, 사용자의 타임 스탬프의 경우 'isalpha'로 검사 할 수 있습니다. 신분증.(더 나은 함수를 작성하십시오.) 또는 첫 번째'sscanf'에서 문자열을 읽어 들인 다음 해당 문자열에서'sscanf ('..., "% d", ...)'를 실행할 수 있습니다. –

답변

3

쉬운 방법 :

char dummy; 
sscanf(userInput, "%d%c %s %f", &timestamp, &dummy, userId, &weight); 
if (!isspace(dummy)) 
    // invalid timestamp input, handle as appropriate 

%d 변환 지정은 %c 변환 지정자에 의해 포착 될 입력 스트림의 첫 번째 숫자가 아닌 문자를 떠날 sscanf을 알려줍니다. 이 문자가 공백이 아닌 다른 문자이면 입력이 유효한 정수 문자열이 아닙니다.

쉽지하지만, IMO 더 강력한 방법 :

char timestampStr[N+1]; // where N is the number of digits in the time stamp 
... 
sscanf(userInput, "%s %s %f", timestampStr, userID, &weight); 

그런 다음 정수 값으로 텍스트를 변환 할 strtol 라이브러리 함수를 사용 :

먼저, 텍스트로 타임 스탬프를 읽고

char *chk; 
int tmp = (int) strtol(timestampStr, &chk, 10); 

chktimestampStr의 첫 번째 비 숫자 문자를 가리 킵니다. 이 timestamp에 아무것도 지정하지 않기 때문에 입력이 유효하지 않은 경우 나는이 방법을 선호

if (*chk == 0 || isspace(*chk)) 
{ 
    timestamp = tmp; 
} 
else 
{ 
    // invalid timestamp input, handle as appropriate 
} 

:이 문자는 공백 이외의 또는 0 종결 인 경우, 입력 문자열은 하지 유효한 정수이었다 ; 이것은 귀하의 목적에 따라 다를 수도 있고 그렇지 않을 수도 있습니다. chux가 지적 하듯이

편집

, 당신은 또한 sscanf의 반환 값을 확인해야합니다 (I 거의 대화 형 입력에 대한 *scanf 기능을 사용하지 않는, 그래서 나는 그것에 대해 생각하지 않음). 첫 번째 경우 결과가 < 4 인 경우 타임 스탬프에 관계없이 문제가 발생하여 전체 행을 버려야합니다. 마찬가지로, 두 번째 경우에 결과가 < 3이면 원하는 입력을 얻지 못했기 때문에 전체 행을 버려야합니다. 실제로

은, 내가 뭘 라인을 읽고 다음 strtok를 사용하여 토큰으로 그것을 깰하고 필요한 모든 숫자 변환을 할 strtol 또는 strtod를 사용하는 사용 fgets입니다.

+1

+1하지만 나는 또한'sscanf()'의 결과를 검사 할 것이다. – chux

관련 문제