문자열이 C에서 다른 문자열로 시작되는지 확인하는 방법
뭐 이런 거 있어요?startsWith(str_a, str_b)
표준 C도서관에서요?
nullbytes로 끝나는2개의 스트링에 포인터를 붙이고 첫 번째 스트링도 두 번째 스트링의 선두에 완전히 표시되는지 여부를 알려 줍니다.
예:
"abc", "abcdef" -> true
"abcdef", "abc" -> false
"abd", "abdcef" -> true
"abc", "abc" -> true
여기에는 표준 함수는 없지만 정의할 수 있습니다.
bool prefix(const char *pre, const char *str)
{
return strncmp(pre, str, strlen(pre)) == 0;
}
우리는 걱정할 필요가 없다.str
보다 짧다pre
왜냐하면 C 표준(7.21.4.4/2)에 따라:
그
strncmp
함수는 다음 값 이하를 비교합니다.n
(null 문자 뒤에 오는 문자는 비교되지 않습니다)가 가리키는 배열의 문자s1
가리킨 배열로s2
."
여기에는 표준 C 함수가 없는 것 같습니다.그래서:
bool startsWith(const char *pre, const char *str)
{
size_t lenpre = strlen(pre),
lenstr = strlen(str);
return lenstr < lenpre ? false : memcmp(pre, str, lenpre) == 0;
}
위의 내용은 알기 쉽고 알기 쉬운데, 좁은 루프에서 작업하거나 매우 큰 스트링을 사용하는 경우에는 양쪽 스트링의 전장을 전면에서 스캔하기 때문에 최적의 퍼포먼스를 얻을 수 없습니다.strlen
wj32나 Christoph와 같은 솔루션은 더 나은 성능을 제공할 수 있습니다(단, 벡터화에 대한 이 코멘트는 C에 대한 저의 지식을 넘어섭니다).또한 Fred Foo의 솔루션을 통해strlen
에str
(그가 옳아요. 만약 당신이 그것을 사용한다면,strncmp
대신memcmp
(매우) 큰 스트링이나 타이트 루프에서의 반복 사용만이 문제가 됩니다만, 문제가 되는 경우는 문제가 됩니다.
나는 아마 함께 갈 것이다.strncmp()
다만, 재미삼아 원시적인 실장:
_Bool starts_with(const char *restrict string, const char *restrict prefix)
{
while(*prefix)
{
if(*prefix++ != *string++)
return 0;
}
return 1;
}
사용하다strstr()
기능. Stra == strstr(stra, strb)
최적화(v.2. - 수정):
uint32 startsWith( const void* prefix_, const void* str_ ) {
uint8 _cp, _cs;
const uint8* _pr = (uint8*) prefix_;
const uint8* _str = (uint8*) str_;
while ( ( _cs = *_str++ ) & ( _cp = *_pr++ ) ) {
if ( _cp != _cs ) return 0;
}
return !_cp;
}
또는 다음 두 가지 접근 방식을 조합할 수도 있습니다.
_Bool starts_with(const char *restrict string, const char *restrict prefix)
{
char * const restrict prefix_end = prefix + 13;
while (1)
{
if ( 0 == *prefix )
return 1;
if ( *prefix++ != *string++)
return 0;
if ( prefix_end <= prefix )
return 0 == strncmp(prefix, string, strlen(prefix));
}
}
편집: strncmp가 0을 반환하는 경우 종단0 또는 길이(block_size)에 도달했는지 알 수 없기 때문에 다음 코드가 작동하지 않습니다.
블럭별로 비교하는 방법도 있습니다.블록이 동일하지 않으면 해당 블록을 원래 함수와 비교합니다.
_Bool starts_with_big(const char *restrict string, const char *restrict prefix)
{
size_t block_size = 64;
while (1)
{
if ( 0 != strncmp( string, prefix, block_size ) )
return starts_with( string, prefix);
string += block_size;
prefix += block_size;
if ( block_size < 4096 )
block_size *= 2;
}
}
상수13
,64
,4096
, 및 의 지수화block_size
그냥 추측일 뿐이야사용된 입력 데이터 및 하드웨어에 대해 선택해야 합니다.
우아한 코드를 쓰는 데는 전문가가 아니지만...
int prefix(const char *pre, const char *str)
{
char cp;
char cs;
if (!*pre)
return 1;
while ((cp = *pre++) && (cs = *str++))
{
if (cp != cs)
return 0;
}
if (!cs)
return 0;
return 1;
}
승인된 버전을 실행했는데 스트링이 너무 길어서 문제가 있었기 때문에 다음 논리를 추가해야 했습니다.
bool longEnough(const char *str, int min_length) {
int length = 0;
while (str[length] && length < min_length)
length++;
if (length == min_length)
return true;
return false;
}
bool startsWith(const char *pre, const char *str) {
size_t lenpre = strlen(pre);
return longEnough(str, lenpre) ? strncmp(str, pre, lenpre) == 0 : false;
}
다음 매크로를 사용합니다.
#define STARTS_WITH(string_to_check, prefix) (strncmp(string_to_check, prefix, ((sizeof(prefix) / sizeof(prefix[0])) - 1)) ? 0:((sizeof(prefix) / sizeof(prefix[0])) - 1))
문자열이 접두사로 시작하는 경우 prexif 길이를 반환합니다.이 길이는 컴파일 시간(크기)으로 평가되므로 런타임 오버헤드가 발생하지 않습니다.
언급URL : https://stackoverflow.com/questions/4770985/how-to-check-if-a-string-starts-with-another-string-in-c
'programing' 카테고리의 다른 글
Axios 매개 변수가 URL에 올바르게 추가되지 않음 (0) | 2022.07.01 |
---|---|
SSR의 Vuex 모듈 재설정 상태 (0) | 2022.07.01 |
컴포넌트 템플릿 내의 Vuex getter에서 업데이트된 값을 얻는 방법 (0) | 2022.07.01 |
Vuetify 폼 검증 - 일치하는 입력을 위한 ES6 규칙 정의 (0) | 2022.07.01 |
Bootstrap-Vue: 요소를 나머지 공간에 채우십시오. (0) | 2022.07.01 |