【问题标题】:Can you help me find a problem with this basic C code你能帮我找出这个基本 C 代码的问题吗
【发布时间】:2021-02-04 13:53:11
【问题描述】:

我正在解决一本 C 编程书籍中的一些问题,以复习字符串。我不知道为什么我的解决方案不起作用。

问题要求编写一个名为 censor 的函数,该函数通过将每次出现的 foo 替换为 xxx 来修改字符串。

我的代码:

int main()
{
    char msg[] = "I love food, you fool.";

    censor(msg);

    puts(msg);

    return 0;
}

void censor(char *str) {
    char *c = str;
    while (c+2 != '\0') {
        if (*c == 'f' && *(c+1) == 'o' && *(c+2) == 'o')
            *c = *(c+1) = *(c+2) = 'x';
        c++;
    }
}

我发现 while 循环运行了大约 1700 次。我很确定 msg[] 会在字符串结尾自动包含一个空字符。

【问题讨论】:

  • *(c+i) 更常见于c[i],甚至*c 通常写成c[0]

标签: c while-loop char c-strings function-definition


【解决方案1】:

如果我理解正确,你可能还没有使用标准的 C 字符串函数,函数 censor 应该使用指针编写。

对于初学者来说,这样的字符串函数应该返回一个指向修改后的字符串的指针。也就是说函数返回类型应该是char *而不是void

while循环中的条件

while (c+2 != '\0') {

等价于

while (c+2 != NULL) {

因为表达式c + 2 具有指针类型char *。所以条件不正确。

此外,一般情况下,如果您甚至会更改条件,例如

while ( *( c+2 ) != '\0') {

如果用户传递的字符串少于两个字符,则循环可能具有未定义的行为。

函数可以定义为如下演示程序所示。

#include <stdio.h>

char * censor( char *s ) 
{
    const char *s1 = "foo";
    const char *s2 = "xxx";
    
    for ( char *p = s; *p; )
    {
        const char *t1 = s1;
        
        while ( *t1 && *t1 == *p )
        {
            ++t1; ++p;
        }
        
        p -= t1 - s1;
        
        if ( *t1 == '\0' )
        {
            for ( const char *t2 =s2; *t2; ++t2 )
            {
                *p++ = *t2;
            }
        }
        else
        {
            ++p;
        }
    }
    
    return s;
}

int main( void ) 
{
    char msg[] = "I love food, you fool.";
    
    puts( msg );
    puts( censor( msg ) );
    
    return 0;
}

程序输出是

I love food, you fool.
I love xxxd, you xxxl

所示函数的代码不依赖于字符串"foo""xxx"。指针s1s2 可以用任何其他长度相等的字符串来初始化。

【讨论】:

    【解决方案2】:

    您正在检查 指针 的值,而不是它所指向的值。所以不要这样:

    while (c+2 != '\0') {
    

    你想要这个:

    while (*(c+2) != '\0') {
    

    【讨论】:

    • 即像往常一样阅读编译器警告。即使在使用建议的答案修复此问题后,请考虑如果传递单个字符串甚至是空字符串,它仍然会被破坏。人们也可以质疑c 的存在意义,因为您可以轻松地使用str 来遍历字符串。
    猜你喜欢
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多