我需要编写我的函数strtok。下面是我的代码。问题是 - 我无法显示结果字符串。在我使用的代码中strcpy(),然后显示新数组。是否可以仅使用指针显示字符串*str?
#include <stdio.h>
#include <string.h>
char* my_strtok(char* s, char* delm){
char W[100];
int i = 0, k = 0, j = 0;
char *ptr;
static char *Iterator;
ptr = s;
if (s == NULL){
s = Iterator;
}
while (s[i] != '\0'){
j = 0;
while (delm[j] != '\0'){
if (s[i] != delm[j])
W[k] = s[i];
else goto It;
j++;
}
ptr++;
i++;
k++;
}
It:
W[i] = 0;
Iterator = ++ptr;
return W;
}
int main(void){
char s[100];
char delm[] = " ";
gets(s);
char newstr[100];
char *str = my_strtok(s, delm);
strcpy(newstr, str);
printf("%s", newstr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
小智 6
strtok 的内部实现已经在这里讨论过:
在您的实现类型中(称其为您的类型,因为它与实际的完全不同),您没有为局部变量“W”动态分配任何内存。因此,当您返回它时,不能保证您会正确接收字符串,因为在调用函数中不再为其保留本地分配给 'W' 的内存。除此之外,代码中还使用了许多不必要的变量。而且,它需要适当的重组。为了您更好地理解,我已经修改了您的代码(尽可能保持您的风格)以完成所需的工作:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
char* my_strtok(char* s, char* delm)
{
static int currIndex = 0;
if(!s || !delm || s[currIndex] == '\0')
return NULL;
char *W = (char *)malloc(sizeof(char)*100);
int i = currIndex, k = 0, j = 0;
while (s[i] != '\0'){
j = 0;
while (delm[j] != '\0'){
if (s[i] != delm[j])
W[k] = s[i];
else goto It;
j++;
}
i++;
k++;
}
It:
W[i] = 0;
currIndex = i+1;
//Iterator = ++ptr;
return W;
}
int main(void)
{
char s[100] = "my name is khan";
char delm[] = " ";
//char newstr[100];
char *str = my_strtok(s, delm);
while(str){
printf("%s", str);
free(str);
str = my_strtok(s, delm);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
赏金:“从可靠和/或官方来源寻找答案。”
我认为GNU GLibC是一个可信的官方来源,对吧?您可以下载的glibc 2.22这里为.tar.gz(25MB)。
提取来源后:
string/strtok.c
#include <string.h>
static char *olds;
#undef strtok
#ifndef STRTOK
# define STRTOK strtok
#endif
/* Parse S into tokens separated by characters in DELIM.
If S is NULL, the last string strtok() was called with is
used. For example:
char s[] = "-abc-=-def";
x = strtok(s, "-"); // x = "abc"
x = strtok(NULL, "-="); // x = "def"
x = strtok(NULL, "="); // x = NULL
// s = "abc\0=-def\0"
*/
char *
STRTOK (char *s, const char *delim)
{
char *token;
if (s == NULL)
s = olds;
/* Scan leading delimiters. */
s += strspn (s, delim);
if (*s == '\0')
{
olds = s;
return NULL;
}
/* Find the end of the token. */
token = s;
s = strpbrk (token, delim);
if (s == NULL)
/* This token finishes the string. */
olds = __rawmemchr (token, '\0');
else
{
/* Terminate the token and make OLDS point past it. */
*s = '\0';
olds = s + 1;
}
return token;
}
Run Code Online (Sandbox Code Playgroud)
string/strspn.c
#include <string.h>
#undef strspn
#ifndef STRSPN
#define STRSPN strspn
#endif
/* Return the length of the maximum initial segment
of S which contains only characters in ACCEPT. */
size_t
STRSPN (const char *s, const char *accept)
{
const char *p;
const char *a;
size_t count = 0;
for (p = s; *p != '\0'; ++p)
{
for (a = accept; *a != '\0'; ++a)
if (*p == *a)
break;
if (*a == '\0')
return count;
else
++count;
}
return count;
}
libc_hidden_builtin_def (strspn)
Run Code Online (Sandbox Code Playgroud)
string/strpbrk.c
#include <string.h>
#undef strpbrk
#ifndef STRPBRK
#define STRPBRK strpbrk
#endif
/* Find the first occurrence in S of any character in ACCEPT. */
char *
STRPBRK (const char *s, const char *accept)
{
while (*s != '\0')
{
const char *a = accept;
while (*a != '\0')
if (*a++ == *s)
return (char *) s;
++s;
}
return NULL;
}
libc_hidden_builtin_def (strpbrk)
Run Code Online (Sandbox Code Playgroud)
sysdeps/x86_64/rawmemchr.S
#include <sysdep.h>
.text
ENTRY (__rawmemchr)
movd %rsi, %xmm1
mov %rdi, %rcx
punpcklbw %xmm1, %xmm1
punpcklbw %xmm1, %xmm1
and $63, %rcx
pshufd $0, %xmm1, %xmm1
cmp $48, %rcx
ja L(crosscache)
movdqu (%rdi), %xmm0
pcmpeqb %xmm1, %xmm0
/* Check if there is a match. */
pmovmskb %xmm0, %eax
test %eax, %eax
jnz L(matches)
add $16, %rdi
and $-16, %rdi
jmp L(loop_prolog)
.p2align 4
L(crosscache):
and $15, %rcx
and $-16, %rdi
movdqa (%rdi), %xmm0
pcmpeqb %xmm1, %xmm0
/* Check if there is a match. */
pmovmskb %xmm0, %eax
/* Remove the leading bytes. */
sar %cl, %eax
test %eax, %eax
je L(unaligned_no_match)
/* Check which byte is a match. */
bsf %eax, %eax
add %rdi, %rax
add %rcx, %rax
ret
.p2align 4
L(unaligned_no_match):
add $16, %rdi
.p2align 4
L(loop_prolog):
movdqa (%rdi), %xmm0
pcmpeqb %xmm1, %xmm0
pmovmskb %xmm0, %eax
test %eax, %eax
jnz L(matches)
movdqa 16(%rdi), %xmm2
pcmpeqb %xmm1, %xmm2
pmovmskb %xmm2, %eax
test %eax, %eax
jnz L(matches16)
movdqa 32(%rdi), %xmm3
pcmpeqb %xmm1, %xmm3
pmovmskb %xmm3, %eax
test %eax, %eax
jnz L(matches32)
movdqa 48(%rdi), %xmm4
pcmpeqb %xmm1, %xmm4
add $64, %rdi
pmovmskb %xmm4, %eax
test %eax, %eax
jnz L(matches0)
test $0x3f, %rdi
jz L(align64_loop)
movdqa (%rdi), %xmm0
pcmpeqb %xmm1, %xmm0
pmovmskb %xmm0, %eax
test %eax, %eax
jnz L(matches)
movdqa 16(%rdi), %xmm2
pcmpeqb %xmm1, %xmm2
pmovmskb %xmm2, %eax
test %eax, %eax
jnz L(matches16)
movdqa 32(%rdi), %xmm3
pcmpeqb %xmm1, %xmm3
pmovmskb %xmm3, %eax
test %eax, %eax
jnz L(matches32)
movdqa 48(%rdi), %xmm3
pcmpeqb %xmm1, %xmm3
pmovmskb %xmm3, %eax
add $64, %rdi
test %eax, %eax
jnz L(matches0)
and $-64, %rdi
.p2align 4
L(align64_loop):
movdqa (%rdi), %xmm0
movdqa 16(%rdi), %xmm2
movdqa 32(%rdi), %xmm3
movdqa 48(%rdi), %xmm4
pcmpeqb %xmm1, %xmm0
pcmpeqb %xmm1, %xmm2
pcmpeqb %xmm1, %xmm3
pcmpeqb %xmm1, %xmm4
pmaxub %xmm0, %xmm3
pmaxub %xmm2, %xmm4
pmaxub %xmm3, %xmm4
pmovmskb %xmm4, %eax
add $64, %rdi
test %eax, %eax
jz L(align64_loop)
sub $64, %rdi
pmovmskb %xmm0, %eax
test %eax, %eax
jnz L(matches)
pmovmskb %xmm2, %eax
test %eax, %eax
jnz L(matches16)
movdqa 32(%rdi), %xmm3
pcmpeqb %xmm1, %xmm3
pcmpeqb 48(%rdi), %xmm1
pmovmskb %xmm3, %eax
test %eax, %eax
jnz L(matches32)
pmovmskb %xmm1, %eax
bsf %eax, %eax
lea 48(%rdi, %rax), %rax
ret
.p2align 4
L(matches0):
bsf %eax, %eax
lea -16(%rax, %rdi), %rax
ret
.p2align 4
L(matches):
bsf %eax, %eax
add %rdi, %rax
ret
.p2align 4
L(matches16):
bsf %eax, %eax
lea 16(%rax, %rdi), %rax
ret
.p2align 4
L(matches32):
bsf %eax, %eax
lea 32(%rax, %rdi), %rax
ret
.p2align 4
L(return_null):
xor %rax, %rax
ret
END (__rawmemchr)
weak_alias (__rawmemchr, rawmemchr)
libc_hidden_builtin_def (__rawmemchr)
Run Code Online (Sandbox Code Playgroud)