C:如果字符串中存在子字符串,则将字符串中的小写字母更改为大写字母

时间:2019-01-14 18:39:30

标签: c arrays string pointers substring

我正在编写一个程序以大写C语言中的字符串。

以下示例说明了我的预期输出:

String:    "hello world"
Substring: "wo"
Output:    "hello WOrld"
String:    "I don't know how to do this"
Substring: "do" 
Output:    "I DOn't know how to DO this"
String:    "mouse is useful thing"
Substring: "use" 
Output:    "moUSE is USEful thing"
String:    "replace occurrences of 'r'"
Substring: "r" 
Output:    "Replace occuRRences of 'R'"

基本上,子字符串在字符串中的任何位置,在原始字符串中大写。

这是我的代码:

void replaceSubstring(char *str, char *substr) {
    char *p = str;
    char *k = substr;
    int substringLength = strlen(k);

    while (*p)
    {
        if (strncmp(p, k, substringLength) == 0)
        {
            for (p; p < p + substringLength; p++)
            {
                *p = *p - 32;
            }
        }
        p++;
    }
    puts(p);
    printf("\n"); 
}

但是,我的代码崩溃了。我的方法是在字符不为'\0'时循环,并检查子字符串是否位于字符串内的某个位置(使用strncmp函数),如果是,我想更改该值将*p的ASCII值减少32,将其变为大写字母。

为什么不起作用?错误在哪里?

2 个答案:

答案 0 :(得分:2)

内部循环的主要问题是p不能同时用作终止目标(p + substringLength)和 作为柜台。就像说for (int i = 0; i < i + 10; i++)i会达到i + 10吗?

您可以尝试将p + substringLength设置为变量len,然后使用该固定的球门柱作为循环终止条件。

第二,使用toupper()进行字符转换。否则,空格和非字母字符也将被修改,从而导致意外行为。例如,空格将变成空的终止字符,使字符串的尾部孤立。

将其放在一起将产生:

for (char *len = p + substringLength; p < len; p++)
{
    *p = toupper(*p);
}

最后,puts(p);不能正常工作。在函数的末尾,p用于遍历字符串,现在指向字符串的末尾,而不是开始。使用puts(str);或只是在调用范围内进行打印即可避免side effects

这是一个完整的例子:

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

void replaceSubstring(char *str, char *substr) {
    char *p = str;
    int substringLength = strlen(substr);

    while (*p)
    {
        if (strncmp(p, substr, substringLength) == 0)
        {
            for (char *len = p + substringLength; p < len; p++)
            {
                *p = toupper(*p);
            }
        }

        p++;
    }
}

int main(void) {
    char s[12] = "hello world";
    replaceSubstring(s, "llo wor");  
    printf("%s\n", s);
    replaceSubstring(s, "ll");  
    printf("%s\n", s);
    replaceSubstring(s, "h");  
    printf("%s\n", s);
    replaceSubstring(s, "hello worldz");  
    printf("%s\n", s);

    char t[28] = "i don't know how to do this";
    replaceSubstring(t, "do");  
    printf("%s\n", t);
    replaceSubstring(t, "'t know");  
    printf("%s\n", t);
    return 0;
}

输出:

heLLO WORld
heLLO WORld
HeLLO WORld
HeLLO WORld
i DOn't know how to DO this
i DOn'T KNOW how to DO this

Try it!

答案 1 :(得分:0)

对于单字符串和单模式,您可以使用kmp。

https://www.geeksforgeeks.org/kmp-algorithm-for-pattern-searching/

对于一组字符串和单个模式,可能需要基于fsm的​​算法。

https://www.geeksforgeeks.org/finite-automata-algorithm-for-pattern-searching/

它们是非常经典的算法,并且已经讲了很多。