본문 바로가기

Lecture/AVR

파싱(parsing) 방법

후헤겔겔겔.....
파싱 방법을 새로 만들었다.
GPS 파싱할때 많이 쓰는 방식으로 변수를 , (콤마)로 구분하고  콤마를 확인하여 숫자를 하나하나 축출하고 , 자릿수를 확인하여 각각의 자리수에 맞게 곱해서 더해주었다. 
(나만 이런식으로 쓴건가?....)

지금은 데이터의 길이를 미리 정해주고 그냥 한번에 뿌려주는 형식을 이용하였다.

// X축 P   I   D Y축P  I   D   추력  기울기 x 기울기Y
//  $000 000 000 000 000 000 0000  000    000 #
//  0123 456 789 012 345 678 9012  345    678 9

이런식으로 출력되게 된다.

그러면 앞에 3자리 3자리 씩 데이터를 끊어서 str->int 로 바꾸어주면 된다.

데이터를 끊어서 저장하는것은 strlcpy()를 이용하였다. 
그리고 str->int 는   atoi()를 이용하였다.

strlcpy() 에서 주의할 점은 str의 끝인 null 을 포함한 길이 이므로 3개의 데이터를 복사하려면 4를 입력해줘야 한다는것이다.
뒤에 null 이 들어가기 때문에 부담없이 atoi()로 변환시켜 주면 된다.

atoi()함수를 보다가 문득 아이디어가 떠올랐는데.....

strtol() 을 이용하는건 어떨까?

long  strtol (const char *__nptr, char **__endptr, int __base)

strtol()은 atoi()함수의 원조격이다. atoi 자체가  (int)strtol(s, (char**)NULL,10); 으로 되어있으니.....
strtol()의 장점은 변환하다가 에러가 발생하면 에러지점의 포인터값을 저장해준다는것이다.  (char** __endptr)
그렇다면 GPS 파싱할때도 strlen()을 이용하여 문자열의 길이를 구해놓고 
그 길이 안에서 strtol()을 사용한다면 GPS 파싱도 궂이 어렵게 하지 않을수 있는건가?......

흠..... 다시 고민되는군.......




아래의 코드가 새로 구현한 코드.....

void getStr(void){
char var[6];
int var1,var2,var3,var4,var5,var6,var7,var8,var9;

unsigned char f_noErr,j,k,i;
f_noErr=0;
f_data=0;

for(i=0; i<RX_BUFFER_SIZE0 ; i++ ){
if( rx_counter0 != 0) str[i] = getUart0();
else str[i]=0;

}


// 컴퓨터 입력 데이터
// X축 P   I   D Y축P  I   D   추력  기울기 x 기울기Y
//  $000 000 000 000 000 000 0000  000    000 #
//  0123 456 789 012 345 678 9012  345    678 9
str[38]=0;
if(str[0]=='$' && str[29]=='#' ){
strlcpy(var,&str[1],4);
var1=atoi(var);
strlcpy(var,&str[4],4);
var2=atoi(var);
strlcpy(var,&str[7],4);
var3=atoi(var);
strlcpy(var,&str[10],4);
var4=atoi(var);
strlcpy(var,&str[13],4);
var5=atoi(var);
strlcpy(var,&str[16],4);
var6=atoi(var);
strlcpy(var,&str[19],5);
var7=atoi(var);
strlcpy(var,&str[23],4);
var8=atoi(var);
strlcpy(var,&str[26],4);
var9=atoi(var);

printf("%d,%d,%d,%d,%d,%d,%d,%d,%d\n   ", var1,var2,var3,var4,var5,var6,var7,var8,var9);

}



이전에 하나하나 노가다로 파싱하던 코드......

j=0;
if(str[j]=='$'){
j++;
//thrust  변환
k=0;
while(str[k+j]!=',' && (k+j)<RX_BUFFER_SIZE0)k++;
if(k>0&& (k<5) && str[j]!='-'){
if(k==1){ thrust_=str[j]-0x30;
}else if(k==2){thrust_=(str[j]-0x30)*10; thrust_+= (str[++j]-0x30);
}else if(k==3){thrust_=(str[j]-0x30)*100; thrust_+= (str[++j]-0x30)*10; thrust_+= str[++j]-0x30;
}else if(k==4){thrust_=(str[j]-0x30)*1000; thrust_+= (str[++j]-0x30)*100; thrust_+= (str[++j]-0x30)*10; thrust_+= str[++j]-0x30;}
j++;

}else if(k>1&& (k<5) && str[j]=='-'){
if(k==2){ thrust_=str[++j]-0x30;
}else if(k==3){thrust_=(str[++j]-0x30)*10; thrust_+= str[++j]-0x30;
}else if(k==4){thrust_=(str[++j]-0x30)*100; thrust_+= (str[++j]-0x30)*10; thrust_+= str[++j]-0x30;
}else if(k==5){thrust_=(str[++j]-0x30)*1000; thrust_+= (str[++j]-0x30)*100; thrust_+= (str[++j]-0x30)*10; thrust_+= str[++j]-0x30;}
thrust_=-thrust_;
j++;
}
 }



새로 구현한 소스는 두줄이 하나의 변수를 얻는거라면
이전의 소스는 위의 코드 전체가 하나의 변수를 구하는 소스이다. 
아래의 코드도 strtol()을 사용하면 획기적으로 줄어들듯도 하군...... 

다음에 시간나면 구현해봐야지....