【问题标题】:Find String Function in [ C ]在 [ C ] 中查找字符串函数
【发布时间】:2021-06-15 05:48:10
【问题描述】:

需要一个函数来检查我是否存在子字符串并给我创建此函数的位置,我想知道 C 标头中是否已经存在类似的东西以及它是如何工作的。

这个自己的函数给出了子字符串Hello world的开始位置!如果我搜索世界给 6 如果找不到字符串,则给 -1

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

int findfstr(const char mainstring[], const char substring[]){
    // int = findstring(mainstring,substring) give position if found and -1 if not

    int main_length = strlen(mainstring); // Read the mainstring length
    int subs_length = strlen(substring); // Read the substring length
    int where = 0; // Set to 0 the var of start position
    int steps = (main_length - subs_length); //Retrive the numbers of the chars without substring
    int cicle = 0; // Set to 0 the var used for increment steps
    
    
    char found_string[subs_length]; // Set the Array to the substring length
    
    if ( subs_length <= main_length){ // If substring is bigger tha mainstring make error
        while (where == 0){ //loop until var "where are equal to 0"
            
            //Stop loop if and when  cicle is bigger than steps
            if (cicle >= steps && where == 0){ where = -1;} 
            
            //retrive the substring and store in found_string
            strncpy(found_string, mainstring+cicle, subs_length); 
            
            found_string[subs_length] = '\0'; //Add terminator char to end string
            
            //If retrived string are equal to substring then set where with clicle value
            if ((strcmp(found_string, substring) == 0 )) { 
                    where = cicle;
                
            }
            cicle++; //add +1 to cicle
            
            
        }
    
    }else{ printf("\n substring is to big \n"); } //error message
    
    return where; 
}

int main(){

    int fs = 0;

    // This is how use the function
    fs = findfstr("Hello world!","world");


    if ( fs > 0 ){ printf("\n String found and start in: %d", fs);}
    if ( fs < 0 ){ printf("\n String not found value: %d", fs);}
return 0;

}

输出:

String found and start in: 6

【问题讨论】:

  • @EugeneSh。我尝试了 strstr 但只检索子字符串而不是位置
  • 它返回一个指针。从原始指针和返回的指针,您可以推断出位置。
  • @EugeneSh。我怎样才能担任这个职位? strstr() return char* 我需要 INT 索引
  • strstr() 返回的是指针而不是索引,但是你可以通过减去指向字符串开头的指针得到索引。

标签: c search substring c-strings function-definition


【解决方案1】:

我想知道C中是否已经存在类似的东西

是的,有。

strstr 是您正在寻找的。见https://man7.org/linux/man-pages/man3/strstr.3.html

如果你想要从字符串开始的偏移量,只需使用指针算法。

类似:

#include <stdio.h>
#include <string.h>
int main(void){
    char* str ="Hello";
 
    char* needle = strstr(str, "ell");  // Search for "ell" in str
    if (needle)
    {
        int offset = needle - str;  // Calculate the offset
        printf("offset is %d\n", offset);
    }
    else
    {
        // not found...
    }
    return 0;
}

输出:

offset is 1

【讨论】:

  • 谢谢你的回答,但你能举个例子,我怎样才能用 strstr 获得字符串的起始位置?
  • 注意减法needle - str结果的类型prtdiff_t。只要差异不大,将其分配给 int 即可。
【解决方案2】:

有标准的 C 字符串函数 strstr 声明为

char *strstr(const char *s1, const char *s2);

这实际上完成了相同的任务。只有它的返回类型与您的函数的返回类型不同。

至于你的函数,它太复杂了,因为任何太复杂的函数都至少有一个可以调用未定义行为的错误。

例如,您在此声明中声明了一个可变长度数组

char found_string[subs_length];

这本身就是一个坏主意,因为可能没有足够的内存来为大字符串分配这样的数组。

所以这个数组的有效索引范围是[0, subs_length)。但是,您使用值 subs_length 作为索引来访问数组之外​​的内存

found_string[subs_length] = '\0';

此外,用作返回类型的类型 int 可能不够大,无法在大字符数组中存储位置。您必须改用 size_t 类型。

这是一个演示程序,它展示了如何在不定义需要程序资源的中间可变长度数组的情况下更简单地定义函数。

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

char * findfstr( const char *s1, const char *s2 )
{
    const char *p = NULL;
    size_t n1 = strlen( s1 );
    size_t n2 = strlen( s2 );
    
    for ( ; p == NULL && !( n1 < n2 ); --n1 )
    {
        if ( strncmp( s1, s2, n2 ) == 0 )
        {
            p = s1;
        }
        else
        {
            ++s1;
        }
    }

    return ( char * )p;
}

int main(void) 
{
    char s1[] = "Hello World";
    const char *s2 = "Hello";
    
    char *p = findfstr( s1, s2 );
    
    if ( p != NULL ) printf( "%" PRIuPTR "\n", p - s1 );
    
    s2 = "World";
    
    p = findfstr( s1, s2 );
    
    if ( p != NULL ) printf( "%" PRIuPTR "\n", p - s1 );
    
    return 0;
}

程序输出是

0
6

要输出两个指针之间的差异,例如使用在标题&lt;inttypes.h&gt; 中声明的宏PRIdPTRPRIuPTR。要声明一个保持两个指针之间差异的变量,请使用在标头 &lt;stddef.h&gt; 中声明的名称 ptrdiff_t

例如

#include <stddef.h>

//...

ptrdiff_t diff = p - s1;

【讨论】:

  • printf( "%" PRIuPTR "\n", p - s1 ) 假定 ptrdiff_tuintptr_t 兼容。合理,但未指定。也许是printf( "%td\n", p - s1 );
  • @chux-ReinstateMonica 是的,可以使用。
猜你喜欢
  • 1970-01-01
  • 2012-03-20
  • 2023-03-25
  • 1970-01-01
  • 2012-11-10
  • 2019-02-01
  • 1970-01-01
  • 2013-06-01
  • 1970-01-01
相关资源
最近更新 更多