C 언어 가공 다중 문자열(strtok r strtok 사용법)

4463 단어
1. strtok 소개
모두가 알다시피 strtok은 사용자가 제공한 분할부호에 따라 (동시에 분리부호도 복수로 할 수 있다. 예를 들어 ",")"\0"을 만날 때까지 문자열을 분할합니다.
예를 들어, 구분자 = ", 문자열 ="Fred, John, Ann"
strtok을 통해 3개의 문자열'Fred''John''Ann'을 추출할 수 있습니다.
위의 C 코드는
 
  
int in=0;
char buffer[]="Fred,John,Ann"
char *p[3];
char *buff = buffer;
while((p[in]=strtok(buf,","))!=NULL) {
i++;
buf=NULL; }

위 코드와 같이 strtok을 처음 실행하려면 목표 문자열의 주소를 첫 번째 인자 (buf=buffer) 로 하고, 그 다음에 strtok은 NULL을 첫 번째 인자 (buf=NULL) 로 해야 한다.포인터 p[]는 분할된 결과를 저장합니다. p[0]="John", p[1]="John", p[2]="Ann",buf는Fred\0John\0Annnn\0이 됩니다.
2. strtok의 약점은 우리의 계획을 바꾸자. 우리는'Fred male 25, John male 62, Anna female 16'문자열을 정리해서 struct에 입력하고 싶다.
 
  
struct person {
char [25] name ;
char [6] sex;
char [4] age;
}

이렇게 하려면, 로 분할된 문자열을 먼저 추출한 다음 공백으로 분할하는 방법이 있습니다.예를 들어'Fred male 25'를 캡처한 다음에'Fred''male''25'로 나눈 다음에 나는 이 과정을 표현하는 작은 프로그램을 썼다.
 
  
#include
#include
#define INFO_MAX_SZ 255
int main()
{
int in=0;
char buffer[INFO_MAX_SZ]="Fred male 25,John male 62,Anna female 16";
char *p[20];
char *buf=buffer;

while((p[in]=strtok(buf,","))!=NULL) {
buf=p[in];
while((p[in]=strtok(buf," "))!=NULL) {
in++;
buf=NULL;
}
p[in++]="***"; //
buf=NULL; }

printf("Here we have %d strings
",in);
for (int j=0; jprintf(">%sreturn 0;
}

이 프로그램 출력은: Here we have 4 strings > Fred < > male < > 25 < * * * < 이것은 단지 작은 데이터일 뿐 우리가 필요로 하는 것이 아닙니다.그런데 왜 이러지?이것은 strtok이 static(정적) 바늘을 사용하여 데이터를 조작하기 때문에 상기 코드의 운행 과정을 분석해 보겠습니다.
빨간색은strtok의 내장 바늘이 가리키는 위치이고 파란색은strtok의 문자열 수정
1. "Fred male 25, John male 62, Anna female 16"//외부 순환
2. "Fred male 25\0John male 62, Anna female 16"//내부 순환 진입
3."Fred\0male 25\0John male 62,Anna female 16"
4."Fred\0male\025\0John male 62,Anna female 16"
5"Fred\0male\025\0John male 62, Anna female 16"//내부 순환이 "\0"을 만나 외부 순환으로 돌아갑니다.
6 "Fred\0male\025\0John male 62, Anna female 16"//외부 순환이 "\0"을 만나 실행이 종료됩니다.
3. strtok 사용r이런 상황에서 우리는 스트로크를 사용해야 한다r, strtok reentrant. char *strtok_r(char *s, const char *delim, char **ptrptr);
strtok에 비해 우리는 strtok에 바늘을 제공해서 조작해야 한다. strtok처럼 조립된 바늘을 사용하는 것이 아니라.코드:
 
  
#include
#include
#define INFO_MAX_SZ 255
int main()
{
int in=0;
char buffer[INFO_MAX_SZ]="Fred male 25,John male 62,Anna female 16";
char *p[20];
char *buf=buffer;

char *outer_ptr=NULL;
char *inner_ptr=NULL;

while((p[in]=strtok_r(buf,",",&outer_ptr))!=NULL) {
buf=p[in];
while((p[in]=strtok_r(buf," ",&inner_ptr))!=NULL) {
in++;
buf=NULL;
}
p[in++]="***";
buf=NULL; }

printf("Here we have %d strings
",in);
for (int j=0; jprintf(">%sreturn 0;
}

이번 출력은 Here we have 12 strings>Fred<>male<>25<>**<>John<>male<>62<>**<>Anna<>female<>16<>**<
위 코드의 작동 과정을 분석해 보겠습니다.
빨간색은strtokr의 outerptr가 가리키는 위치, 자색은strtokr의 innerptr가 가리키는 위치, 파란색은strtok로 문자열 수정
1. "Fred male 25, John male 62, Anna female 16"//외부 순환 2."Fred male 25\0John male 62, Anna female 16"//내부 순환에 들어갑니다."Fred\0male 25\0 John male 62, Anna female 16"4 "Fred\0male\025\0 John male 62, Anna female 16"//내부 순환에서 "\0"을 만나면 외부 순환 6"Fred\0male\025\0 John male 62\0 Anna female 16"//내부 순환에 들어갑니다
원래 이 함수는 원열을 수정하였다.
따라서char*test2 = "feng,ke,wei"를 첫 번째 매개 변수로 전송할 때 위치 ①에서test2가 가리키는 내용이 문자 상수 구역에 저장되기 때문에 이 구역의 내용은 수정할 수 없기 때문에 메모리 오류가 발생할 수 있습니다.한편chartest1[]="feng,ke,wei"의test1이 가리키는 내용은 창고에 저장되어 있기 때문에 수정할 수 있습니다

좋은 웹페이지 즐겨찾기