【问题标题】:Given a string write a program to generate all possible strings by replacing ? with 0 and 1?给定一个字符串,编写一个程序,通过替换来生成所有可能的字符串?有 0 和 1?
【发布时间】:2015-10-18 21:03:15
【问题描述】:

我已经编写了这段代码,它适用于 a?b?c?和 a?b?c?d?但是对于 a?b?c?d?e?它最后给出了一个额外的垃圾值。在 s 的末尾附加了 '\0' 字符,然后为什么以及如何读取该垃圾值。我试图通过在代码之间放置 printf 语句来调试它,但无法解决它。请帮忙。

#include<stdio.h>
void print(char* s,char c[],int l)
{
    int i,j=0;
    for(i=0;s[i]!='\0';i++)
    {
        if(s[i]=='?')
        {
            printf("%c",c[j]);
            j++;
        }
        else
            printf("%c",s[i]);
    }
    printf(", ");
}
void permute(char *s,char c[],int l,int index)
{
    if(index==l)
    {
        print(s,c,l);
        return;
    }
    c[index]='0';
    permute(s,c,l,index+1);
    c[index]='1';
    permute(s,c,l,index+1);
}
int main()
{
    char s[10],c[10];
    printf("Enter a string.");
    scanf("%s",s);
    int i,ct=0;
    for(i=0;s[i]!='\0';i++)
    {
        if(s[i]=='?')
            ct++;
    }
    permute(s,c,ct,0);
    return 0;
}

我的输出是这样的:-

a0b0c0d0e0♣,a0b0c0d0e1♣,

...等等。

【问题讨论】:

    标签: c arrays string recursion scanf


    【解决方案1】:

    从您的代码中我们可以看出,数组定义为char s[10],输入为

    a?b?c?d?e?

    一个输入,不能与空终止符一起保存在s

     scanf("%s",s);
    

    您需要使用更大的数组。否则,为了尝试在输入后添加终止的 null,正在对调用 undefined behaviour 的越界内存进行访问。

    也就是说,永远不允许 unbound 输入到有限大小的数组,始终使用字段宽度来限制输入长度(换句话说,保留空间对于空终止符),如

     scanf("%9s",s);
    

    【讨论】:

    • 所以我应该改用 malloc 来避免这些错误吗?
    • @Arcana 没有必要。只要确保您的输入不会溢出分配的缓冲区。使用字段宽度是实施限制的好方法。
    • 开发者。应该在除 RAM 受限的嵌入式环境之外的所有环境中停止字节计数。如果用户要输入一个字符串,则将其设为 256 长。输入“256”比计算字节数和数组大小出错更快、更安全。
    • 当我向下滚动时,我只是在写关于缓冲区溢出的评论,而你已经写了。
    • @Martin James 我知道问这个问题有点晚了,但我不明白你的评论“除了 RAM 受限的嵌入式环境”是什么意思。如果我理解正确,您只是说使用字段宽度很好。?
    【解决方案2】:

    在 C 中实际看到 String 中发生的情况是,每次它最后都附加一个 '\0' 字符。

    现在请注意,在 C 中没有什么叫做字符串。

    这是一个字符数组。

    所以如果你这样定义-

    char s[10]
    

    这实际上接受一个少于 9 个字符的数组,因为最后一个是 '\0' 字符。

    如果添加超过 9 个字符,则会给出错误输出。

    【讨论】:

      【解决方案3】:

      代码在此处生成正确的输出,但请注意,对于大小大于或等于 10 个字符的字符串,它具有未定义的行为,因为这是缓冲区的大小。

      因此,对于a?b?c?d?e?,您需要一个至少包含 11 个字符的缓冲区,以说明空终止符。你应该把s 变大。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-29
        相关资源
        最近更新 更多