繁体   English   中英

通过 function c 传递带有指针的字符串

[英]passing string with pointer through function c

我,我正在尝试编写此代码,它应该计算不包括在字符串中的 substring 的数量,例如(如下),主要是我尝试使用指针在不使用 arrays 的情况下使用字符串,但它没有用完全没有!!

// count_target_string("abc of", "of") -> 1
// count_target_string("abcof", "of")  -> 0
// count_target_string("abc of abc of", "of") -> 2 


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int countTargetString(char* text , char* string){
        
        char d[]=" ";
        char * portion = strtok(text,d);
        int result=0;
        while (portion!=NULL){
            if (strcmp(portion,string)==0){
                result++;
            }
            portion = strtok(NULL,d);
        }
        return result;
    }
    
    
    int main(){
       
        printf("%d\n",countTargetString("abc of abc of","of"));
     
         char *test ="abc of abc of";
         char *d = "of";
         printf("%d\n",countTargetString(test,d));
    
        return 0;
    }
  1. strtok修改字符串。
  2. char *test ="abc of abc of"; 定义指向字符串字面量的指针。 修改字符串文字会调用未定义行为 (UB)。 这就是为什么您的代码“根本不起作用”如果您将字符串文字引用直接传递给 function (即使用字符串文字作为参数) countTargetString("abc of abc of","of")); .

您的指针必须引用可修改的字符串:

int main()
{
    char mystring[] = "abc of abc of";
    char *test = mystring;
    char *d = "of";
    printf("%d\n",countTargetString(test,d));
}

在 function countTargetString的两个调用中

 printf("%d\n",countTargetString("abc of abc of","of"));
 
 char *test ="abc of abc of";
 char *d = "of";
 printf("%d\n",countTargetString(test,d));

您正在传递指向字符串文字的指针。

尽管在 C 中与 C++ 字符串文字具有非常量字符类型 arrays 相对,但您可能不会更改字符串文字。 任何更改字符串文字的尝试都会导致未定义的行为。

来自 C 标准(6.4.5 字符串文字)

7 不确定这些 arrays 是否不同,只要它们的元素具有适当的值。 如果程序尝试修改这样的数组,则行为未定义。

function strtok更改插入终止零字符 '\0' 的源字符串以提取子字符串。

即使在 C 中,使用限定符const声明指向字符串文字的指针也总是更好。

您可以使用 function strstr而不是 function strtok

这是一个演示程序。

#include <stdio.h>
#include <string.h>
#include <ctype.h>

size_t countTargetString( const char *s1, const char *s2 )
{
    size_t count = 0;
    size_t n = strlen( s2 );

    for ( const char *p = s1; ( p = strstr( p, s2 ) ) != NULL; p += n )
    {
        if ( ( p == s1 || isblank( ( unsigned char )p[-1] ) ) &&
             ( p[n] == '\0' || isblank( ( unsigned char )p[n] ) ) )
        {
            ++count;
        }
    }

    return count;
}

int main( void )
{
     printf("%zu\n",countTargetString("abc of abc of","of"));
     
     const char *test ="abc of abc of";
     const char *d = "of";

     printf("%zu\n",countTargetString(test,d));
}

程序 output 是

2
2

如您所见,function 参数也使用限定符const声明,因为 function 不会更改传递的字符串。

请注意,无论如何要计算字符串中子字符串的出现次数,更改原始字符串是一个坏主意。

虽然strtok不适用于字符串文字,但可以使用strspnstrcspn

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int countTargetString(char* text , char* string){
    char d[]=" ";
    int result = 0;
    size_t span = 0;
    while ( *text) {
        text += strspn ( text, d);
        span = strcspn ( text, d);
        if ( strncmp ( text, string, span)) {
            ++result;
        }
        text += span;
    }
    return result;
}


int main( void) {

    printf("%d\n",countTargetString("abc of abc of","of"));

     char *test ="abc of abc of";
     char *d = "of";
     printf("%d\n",countTargetString(test,d));

    return 0;
}
int count_substr(const char* target, const char* searched) {
    int found = 0;
    unsigned long s_len = strlen(searched);
    for (int i = 0; target[i]; i++) {
        // use memcmp to NOT compare the null terminator of searched
        if (memcmp(target + i, searched, s_len) == 0) {
            found++;
            i += s_len - 1;
        }
    }
    return found;
}

这是 substring 计数的一个非常基本的实现。 为了获得最快的解决方案,请从 wikipedia 或任何您想要的地方复制 boyer moore 模式匹配算法,并将其修改为匹配而不是终止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM