微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

这段代码中的 for 循环有什么问题?

如何解决这段代码中的 for 循环有什么问题?

我正在阅读The C Programming Language这本书,但我无法弄清楚我在这个练习中的代码有什么问题。

该练习要求您实现一个版本的 squeeze() 函数,该函数删除 s1 中与字符串 s2 中任何字符匹配的每个字符。

这是我的代码

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

int main ()
{
    char s1[100];
    char s2[100];
    int c;
    int i;
    int j;
    int flag=0;
    char s3[100];

    printf("TYPE THE FirsT STRING\n");
    for(i=0;s1[i-1]!='\n';i++)
    {
        scanf("%c",&s1[i]);
    }


    printf("\n\nTYPE THE SECOND STRING\n");
    for(i=0;s2[i-1]!='\n';i++)
    {
        scanf("%c",&s2[i]);
    }


    for(i=0;s1[i]!='\n';i++)/*sets the "i" character of s1 to be compared*/
    {
        for(j=0;s2[j]!='\n';j++)/*compares the "i" character in s1 with
        {                         every character on s2*/
            if(s1[i]==s2[j])
            {
                flag=1;/*sets the flag variable to one if it finds 2 equal 
                break;   characters and stops the looP*/
            }
        }
        if(flag!=1)/*if it have not found a matching pair of chacters,{            this part copies the s1 char to s3*/
            s3[i]=s1[i];
        }
        flag=0;
        printf("\n");
    }
    printf("\n\n%s",s3);

    return 0;
}

问题是,如果我在 s1 中输入“test”,在 s2 中输入“second”,它只会打印“t”。一旦找到匹配的对,它就会停止。 flag 工作不正常?我在这个练习中超过 2 小时,无法解决

解决方法

for (i = 0; s1[i-1] != '\n'; i++)

此循环第一次迭代的谓词将访问超出边界的s1[-1],并依次调用undefined behavior。涉及 s2 的循环也有同样的问题。

此外,您的字符串永远不会以 NUL 结尾,并且它们的缓冲区很容易通过 scanf 溢出。

您有多个跨多行的 /* */ 注释实例,它们注释掉了您的代码部分:两个开头的 {break

即使解决了评论的问题

if (flag != 1) {
    s3[i] = s1[i];
}

会在你的最后一根弦上留下洞。您需要一个单独的 s3 索引计数器,它只会随着字符串长度的增加而增加。

一个简单的例子,我们初始化我们的缓冲区(特别是这个 NUL 终止 s3),并使用 fgets 来限制我们的输入。

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

int main(void) {
    char s1[100] = { 0 },s2[100] = { 0 },s3[100] = { 0 };
    int flag = 0;
    size_t k = 0;

    if (
        !fgets(s1,sizeof s1,stdin) ||
        !fgets(s2,sizeof s2,stdin)
    ) {
        fprintf(stderr,"Could not read input.\n");
        return EXIT_FAILURE;
    }

    for (size_t i = 0; s1[i] && s1[i] != '\n'; i++) {
        for (size_t j = 0; s2[j] && s2[j] != '\n'; j++) {
            if (s1[i] == s2[j]) {
                flag = 1;
                break;
            }
        }

        if (flag == 0)
            s3[k++] = s1[i];
        flag = 0;
    }

    printf("%s\n",s3);
}

或者,使用strchr,我们可以组成一个整洁的函数:

#include <string.h>

void squeeze(char *dest,const char *source,const char *filter) {
    for (; *source; source++)
        if (!strchr(filter,*source))
            *dest++ = *source;

    *dest = '\0';
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。