C에서 strtok과 strsep의 차이점은 무엇입니까?
이 에 가 해 요 요 해 이 가 에 strtok()
그리고.strsep()
장점과 입니까? 그들의 장점과 단점은 무엇입니까?그리고 내가 왜 다른 것보다 하나를 고르겠어요.
와 와 의 한가지 주요한 차이점은strtok()
는 C 표준으로 표준화되어 있지만(따라서 POSIX로도 표준화되어 있음), 표준화되어 있지는 않습니다(C 또는 POSIX에 의해; GNU C 라이브러리에서 이용할 수 있으며 BSD에서 기원함).따라서, 휴대용 코드는 사용할 가능성이 더 높습니다.strtok()
strsep()
.
또 다른 차이점은 전화가strsep()
수 ,른는수만될할을수은다의할수다otht은n른nesu의ste는,,strtok()
이 할 수 ) 이수할만)만수(록할u이( )strtok_r()
)를 사용합니다.strsep()
도서관에서는 다른 코드를 실수로 끊지 않습니다. 반면에strtok()
. 다른 을리다야기다야r는nget른e는any을리dt .strtok()
동시에 라이브러리 함수를 호출할 수 없습니다.
의 매뉴얼 strsep()
kernel.org 에서 다음과 같이 말합니다.
strsep() 함수는 strtok(3)의 대체 함수로 도입되었는데, strtok(3)은 빈 필드를 처리할 수 없기 때문입니다.
따라서 다른 중요한 차이점은 조지 갈이 그의 답변에서 강조한 것입니다.strtok()
토큰 에 여러 를 허용하는 ,는일에러를는면큰면는를strsep()
은 토큰 간의 단일 구분 기호를 예상하고 인접 구분 기호를 빈 토큰으로 해석합니다.
둘다요.strsep()
그리고.strtok()
할 수 둘 다 력한분다수둘할를기에다을을을의고둘기에(lny다eahds다을uhdrts력mefrerydr( ).'\0'
토큰 종료 후 분리막 위로 이동합니다).
언제 사용합니까?
- 당신은 사용할 것입니다.
strsep()
토큰 간에 여러 구분자를 허용하는 대신 빈 토큰을 원할 때, 휴대성에 신경 쓰지 않을 때. - 당신은 사용할 것입니다.
strtok_r()
토큰 간에 여러 구분자를 허용하고 빈 토큰을 원하지 않을 때(그리고 POSIX는 사용자에게 충분히 휴대할 수 있습니다). - 만은 합니다만 합니다.
strtok()
수 있을 한번생명을 위협하는 상황에서 벗어날 수 있을 정도로 오랫동안 사용해야 합니다. 그러면 다시 한번 사용을 포기하게 됩니다.그것은 독이 있습니다. 사용하지 마십시오.자신의 것을 쓰는 것이 더 나을 것입니다.strtok_r()
아니면strsep()
다를 사용하는strtok()
.
.strtok()
독이 있다고요?
strtok()
함수는 라이브러리 함수에 사용되면 독이 됩니다.라이브러리 함수에서 다음을 사용하는 경우strtok()
, 하게 되어야 되어야 하게 .
그 이유는:
- 이 이 인 인 를 사용하는 경우
strtok()
를는의를s도 사용하는 합니다.strtok()
기능을 합니다. , 합니다 을 합니다 을 . - 가 를
strtok()
은 당신 의 , 은 의 을 할 입니다 의 입니다 할 을 의 의strtok()
. - 스레드라면 에서 이 의 에서 할 인 할 에서 이 을 사용할 수 있습니다.
strtok()
-정에에의에faet에정–의nye의 순서에 걸쳐strtok()
호출
이 문제의 근본은 다음을 허용하는 호출 사이의 저장 상태입니다.strtok()
중단된 곳에서 계속할 겁니다문제를 해결할 합리적인 방법은 "사용하지 않음" 이외에는 없습니다.strtok()
".
- 을 사용할 수 .
strsep()
가능한 경우에는 - 가능하다면 POSIX를 사용할 수 있습니다.
- 사용 가능하다면 마이크로소프트의 것을 사용할 수 있습니다.
- Annex1 기능 ISO/IEC 9899:2011 Annex K.3.7.3.1 을 할 을 할
strtok_s()
는 둘 다 , 는 의 는 의 .strtok_r()
마이크로소프트 사의strtok_s()
.
BSDstrsep()
:
char *strsep(char **stringp, const char *delim);
포식스strtok_r()
:
char *strtok_r(char *restrict s, const char *restrict sep, char **restrict state);
마이크로소프트strtok_s()
:
char *strtok_s(char *strToken, const char *strDelimit, char **context);
K strtok_s()
:
char *strtok_s(char * restrict s1, rsize_t * restrict s1max,
const char * restrict s2, char ** restrict ptr);
에는 에서와 가 의 가 의 가 에는 strtok()
.
GNU C 라이브러리 매뉴얼 - 문자열에서 토큰 찾기:
의 의 한가지
strsep
그리고.strtok_r
에 구분 에 둘 력에의가에둘상어는우분우는어s력상tfstrsep
구분 기호의 각 문자 쌍에 대해 빈 문자열을 반환합니다.이는 프로그램이 일반적으로 다음에 대해 테스트해야 함을 의미합니다.strsep
처리하기 전에 빈 문자열을 반환합니다.
1 의 첫 번째 strtok()
그리고.strsep()
는 입력 문자열의 연속 구분 문자를 처리하는 방식입니다.
가 을 합니다 합니다 을 가 strtok()
:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
const char* teststr = "aaa-bbb --ccc-ddd"; //Contiguous delimiters between bbb and ccc sub-string
const char* delims = " -"; // delimiters - space and hyphen character
char* token;
char* ptr = strdup(teststr);
if (ptr == NULL) {
fprintf(stderr, "strdup failed");
exit(EXIT_FAILURE);
}
printf ("Original String: %s\n", ptr);
token = strtok (ptr, delims);
while (token != NULL) {
printf("%s\n", token);
token = strtok (NULL, delims);
}
printf ("Original String: %s\n", ptr);
free (ptr);
return 0;
}
출력:
# ./example1_strtok
Original String: aaa-bbb --ccc-ddd
aaa
bbb
ccc
ddd
Original String: aaa
에서 을 에서 을 을 볼 수 있습니다."bbb"
그리고."ccc"
푸strtok()
는 연속된 구분 기호 문자의 발생을 나타냅니다.그리고 또.strtok()
입력 문자열을 수정합니다.
가 을 합니다 합니다 을 가 strsep()
:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
const char* teststr = "aaa-bbb --ccc-ddd"; //Contiguous delimiters between bbb and ccc sub-string
const char* delims = " -"; // delimiters - space and hyphen character
char* token;
char* ptr1;
char* ptr = strdup(teststr);
if (ptr == NULL) {
fprintf(stderr, "strdup failed");
exit(EXIT_FAILURE);
}
ptr1 = ptr;
printf ("Original String: %s\n", ptr);
while ((token = strsep(&ptr1, delims)) != NULL) {
if (*token == '\0') {
token = "<empty>";
}
printf("%s\n", token);
}
if (ptr1 == NULL) // This is just to show that the strsep() modifies the pointer passed to it
printf ("ptr1 is NULL\n");
printf ("Original String: %s\n", ptr);
free (ptr);
return 0;
}
출력:
# ./example1_strsep
Original String: aaa-bbb --ccc-ddd
aaa
bbb
<empty> <==============
<empty> <==============
ccc
ddd
ptr1 is NULL
Original String: aaa
두 의 빈 에서두 의 을 할 를 됨 를 됨 에서 )을 볼 수 .<empty>
) bbb
그리고.ccc
두 빈은 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ."--"
에 사이에"bbb"
그리고."ccc"
.strsep()
를다a를m호dr분ra다 .' '
"bbb"
은 구분 를 , 은 를 했습니다 했습니다 로 했습니다.'\0'
ㅇ"bbb"
이에. . 에.strsep()
른분호를다를 찾았습니다.'-'
를 . 를 과 과 를 '\0'
문자를 입력하고 빈 문자열을 반환합니다.다음 구분 기호 문자도 마찬가지입니다.
연속된 구분 기호 문자는 Null 문자(즉, 값이 있는 문자)로 포인터를 반환할 때 표시됩니다.'\0'
).
strsep()
입력 문자열과 주소가 첫 번째 인수로 전달된 포인터를 수정합니다.strsep()
.
은,strtok()
문자열 내의 현재 구문 분석 위치를 추적하기 위해 정적 변수에 의존합니다.이 구현에서는 두 번째 문자열을 시작하기 전에 하나의 문자열을 완전히 구문 분석해야 합니다.하지만 이것은 사실이 아닙니다.strsep()
.
호출 strtok()
nstrtok()
완료되지 않았습니다.
#include <stdio.h>
#include <string.h>
void another_function_callng_strtok(void)
{
char str[] ="ttt -vvvv";
char* delims = " -";
char* token;
printf ("Original String: %s\n", str);
token = strtok (str, delims);
while (token != NULL) {
printf ("%s\n", token);
token = strtok (NULL, delims);
}
printf ("another_function_callng_strtok: I am done.\n");
}
void function_callng_strtok ()
{
char str[] ="aaa --bbb-ccc";
char* delims = " -";
char* token;
printf ("Original String: %s\n", str);
token = strtok (str, delims);
while (token != NULL)
{
printf ("%s\n",token);
another_function_callng_strtok();
token = strtok (NULL, delims);
}
}
int main(void) {
function_callng_strtok();
return 0;
}
출력:
# ./example2_strtok
Original String: aaa --bbb-ccc
aaa
Original String: ttt -vvvv
ttt
vvvv
another_function_callng_strtok: I am done.
function_callng_strtok()
만 토큰쇄만"aaa"
그리고 입력 문자열의 나머지 토큰을 인쇄하지 않습니다. 왜냐하면 그것이 호출하기 때문입니다.another_function_callng_strtok()
h를strtok()
그리고 그것은 정적 포인터를 설정했습니다.strtok()
NULL
모든 토큰을 추출하는 것이 끝나면.통제권은 다시 다음으로 넘어갑니다.function_callng_strtok()
while
리,strtok()
다NULL
를 가리키는 정적 포인터 때문에NULL
조건을을는것프것e는d을고eh프로 만듭니다.false
루프 출구도 있고요.
호출 strsep()
nstrsep()
완료되지 않았습니다.
#include <stdio.h>
#include <string.h>
void another_function_callng_strsep(void)
{
char str[] ="ttt -vvvv";
const char* delims = " -";
char* token;
char* ptr = str;
printf ("Original String: %s\n", str);
while ((token = strsep(&ptr, delims)) != NULL) {
if (*token == '\0') {
token = "<empty>";
}
printf("%s\n", token);
}
printf ("another_function_callng_strsep: I am done.\n");
}
void function_callng_strsep ()
{
char str[] ="aaa --bbb-ccc";
const char* delims = " -";
char* token;
char* ptr = str;
printf ("Original String: %s\n", str);
while ((token = strsep(&ptr, delims)) != NULL) {
if (*token == '\0') {
token = "<empty>";
}
printf("%s\n", token);
another_function_callng_strsep();
}
}
int main(void) {
function_callng_strsep();
return 0;
}
출력:
# ./example2_strsep
Original String: aaa --bbb-ccc
aaa
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
<empty>
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
<empty>
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
bbb
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
ccc
Original String: ttt -vvvv
ttt
<empty>
vvvv
another_function_callng_strsep: I am done.
여기 보시는 것처럼, 전화를 합니다.strsep()
하나의 문자열을 완전히 파싱하기 전에는 아무런 차이가 없습니다.
의 .strtok()
그리고.strsep()
다둘력을는다다다는ths을 .strsep()
는 Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ Δ strtok()
위에 예시한 바와 같이
스트렙에서:
strsep() 함수는 strtok() 함수를 대체하기 위한 것입니다.strtok() 함수는 휴대성의 이유로 선호되어야 하지만(ISO/IEC 9899:1990('ISO C90'') 빈 필드, 즉 두 개의 인접한 구분 문자로 구분되는 필드를 탐지하거나 한 번에 하나 이상의 문자열에 사용할 수 없습니다.strsep() 함수는 4.4에서 처음 나타났습니다.BSD.
참고용:
언급URL : https://stackoverflow.com/questions/7218625/what-are-the-differences-between-strtok-and-strsep-in-c
'source' 카테고리의 다른 글
Android에서 의도란? (0) | 2023.09.11 |
---|---|
질의 결과를 기반으로 하위 질의 가능 UNION ALL 만들기 (0) | 2023.09.11 |
Python에서 C를 호출하는 기능 (0) | 2023.09.11 |
봄 부팅 애플리케이션에서 AWS SDK를 초기화하는 방법은? (0) | 2023.09.11 |
C/C++에서 Windows 기능을 후크하려면 어떻게 해야 합니까? (0) | 2023.09.11 |