2014-02-28 11 views
1

는이 코드를 가지고이 tokenHolder의 getline 및 strtok를 통해 토큰 화 된 사용자 입력으로부터 토큰 문자의 입력을 보유Seg 오류가 C에서 isdigit()으로 발생합니까?

#include <ctype.h> 

char *tokenHolder[2500]; 

for(i = 0; tokenHolder[i] != NULL; ++i){ 

     if(isdigit(tokenHolder[i])){ printf("worked"); } 

. tokenHolder 에 isdigit을 사용하려고하면 seg 오류가 발생하며 이유는 확실하지 않습니다.

+2

'tokenHolder'가'char *'의 배열 인 경우,'tokenHolder [i]! = '\ 0''는 의미가 없습니다. 'tokenHolder [i]! = NULL'와 같습니다. –

+0

@DietrichEpp 나는 그것을 편집 해 주셔서 감사합니다. – user2757849

답변

3

당신이 인덱스 tokenHolder[i], 당신이 통과 될 때 char *isdigit()char *의 배열이며, isdigit()하지 않습니다 : 코드의 나머지 부분의 모습에서, 당신은 정말 정의 할 포인터를 받아 들인다.

당신은 아마 두 번째 루프를 누락하거나 필요

if (isdigit(tokenHolder[i][0])) 
    printf("working\n"); 

가 줄 바꿈을 잊지 마십시오.

루프 테스트가 이상합니다. 일반적으로 '널 포인터'는 0 또는 NULL으로 지정하고 '\0'으로 표시하지 않습니다. 그것은 단지 사람들을 오도합니다.

또한 컴파일러 경고에주의해야합니다! 경고와 함께 컴파일되는 코드를 게시하지 마십시오. (최소한) 경고가 무엇인지 지정하여 사람들이 컴파일러에서 무엇을 말하고 있는지 볼 수 있습니다. 컴파일러가 까다로워지면서 경고가 나오지 않도록해야합니다.

토큰 배열의 값이 모두 숫자인지 테스트하려는 경우 test_integer() 함수를 사용해야 문자열을 숫자로 변환하고 변환에서 모든 데이터를 사용하지 않는지 알 수 있습니다 문자열 (또는 선행 공백과 후행 공백을 허용 할 수 있습니다). strtok() 등으로 찾은 문자열 토큰으로하려는 작업에 대한 문제 사양이 명확하지 않습니다.왜 당신이 코어 덤프 점점에 관해서는

:

isdigit에() 매크로 코드는 종종를 약

#define isdigit(x) (_Ctype[(x)+1]&_DIGIT) 

당신이 포인터를 제공 할 때, 그것은 (매우 큰으로 처리됩니다 (일반적으로) 257 개의 값 배열에 오프셋을 적용하고 범위를 벗어난 메모리에 액세스하기 때문에 세그먼트 오류가 발생합니다. +1은 EOFEOF-1 일 때 isdigit()으로 전달할 수 있습니다. 이는 일반적인 값이지만 필수는 아니지만 필수입니다. isdigit()과 같은 매크로/기능은 문자가 unsigned char —이고 대개 0..255 범위이므로 유효한 입력으로 — 또는 EOF를 사용합니다.

0

isdigit으로 전달하기 전에 입력을 unsigned char으로 전송하고 싶습니다.

if(isdigit((unsigned char)tokenHolder[i])){ printf("worked"); } 

가장 일반적인 부호화 방식에서는, USASCII 범위를 벗어나는 문자 (예를 들어, 움라우트, 억양, 묘 등 어떤 문자) char가 체결되는 일반적인 경우와 음수를 표시한다. 이 세그먼트 오류가 발생하는 방법에 관해서

(islower, isupper 등과 함께)들은 비트 필드의 표를 이용하여 구현되고, 함수를 호출 할 때 isdigit 추월 값이 지표로서 사용 테이블에. 음수는 테이블 밖에서 (잘) 색인을 잡으려고합니다.

처음에는 알지 못했지만 tokenHolder (예상) 유형이 예상 한/사용 예정 유형이 아니기 때문에 문제가 발생했습니다. tokenHolder 이후

char tokenHolder[2500]; 
+1

컴파일 경고를 quells하지만 여전히 unsigned char로 변환 된 포인터를'isdigit()'로 전달합니다. –

+0

char가 왜 부정적인지 묻는 것에 신경 쓰지 않는다면, 컴파일러가 다른 유형으로 인해 값을 잘라 버릴 필요가 있습니까? 죄송합니다. C 언어에 익숙하지 않아요. – user2757849

+1

@ user2757849 :'isdigit()'매크로의 코드는 대개 '#define isdigit (x) (_Ctype [(x) +1] & _ DIGIT)'입니다. 포인터를 제공하면 257 개의 값 배열에 대해 매우 큰 (양수 또는 음수) 오프셋으로 처리됩니다. ('EOF'가'-1' 일 때'isdigit()'에 전달할 수 있습니다. 보통 -1이지만 필수는 아닙니다.) –

2

의 배열을 문자의 간단한 배열이 아닌 문자의 포인터로 선언하고 있습니다. 또한 배열을 초기화하거나 나중에 값을 할당해야합니다. 초기화되지 않았거나 할당되지 않은 배열 구성원의 값을 읽으면 정의되지 않은 동작이 호출됩니다.

char tokenHolder[2500] = {0}; 

for(int i = 0; tokenHolder[i] != '\0'; ++i){ 

    if(isdigit(tokenHolder[i])){ printf("worked"); } 

참고로, 코드가 올바르지 않을 수 있다는 컴파일러 경고를 간과 할 수 있습니다. isdigitint이고, char *int과 호환되지 않으므로 컴파일러가 이에 대한 경고를 생성해야합니다.