为什么此代码产生无限循环?

发布于 2025-01-22 09:43:36 字数 491 浏览 0 评论 0原文

#include <Stdio.h>
#include <string.h>

int main(){
    char str[51];
    int k = 1;
    printf("Enter string\n");
    scanf("%s", &str);
    for(int i = 0; i < strlen(str); i++){
        while(str[k] != '\0')){
            if(str[i] == str[k]){
                printf("%c", str[i]);
                k++;
            }
        }
    }

    return 0;
}

这是简单的C代码,检查字符串中的重复字符并打印字符。我不明白为什么它会产生无限的循环。内部循环应在str [k]到达零终端时停止,但程序无限继续。

#include <Stdio.h>
#include <string.h>

int main(){
    char str[51];
    int k = 1;
    printf("Enter string\n");
    scanf("%s", &str);
    for(int i = 0; i < strlen(str); i++){
        while(str[k] != '\0')){
            if(str[i] == str[k]){
                printf("%c", str[i]);
                k++;
            }
        }
    }

    return 0;
}

It is simple C code that checks for duplicate characters in string and prints the characters. I am not understanding why it is producing an infinite loop. The inner while loop should stop when str[k] reaches the null terminator but the program continues infinitely.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏の忆 2025-01-29 09:43:36

要知道

  • 您不需要将变量str的地址传达到scanf()
  • 不使用“%s”,使用“%&lt; w width&gt; s”,避免 buffer-overfloflfloflfloflfloflflofl
  • 代码> scanf()转换是否成功,通过检查其返回值
  • 始终使用size_t通过任何数组
  • i&lt; strlen(str),使循环的时间复杂性 o(n 3 ,而不是 o(n 2 ,这也不是很好,您应该检查str [i]!= 0。但是,c的许多现代编译器都会顺其自然。
  • #include&lt; stdio.h&gt;这是非常错误的,stdio.h!= stdio.h
  • call to printf()可以使用puts()putc()在没有任何特殊格式的情况下优化,现代编译器也可以优化
  • while(str [k]) !='\ 0')){具有括号(')'
  • 初始化您的变量str使用{},这将把0分配给str的所有元素

更好地实现

我对此问题的实现是创建一个初始化的字符列表(256 max),然后添加1个到该列表中字符的ASCII值(来自str)。之后,打印那些值大于1的字符。

  • 时间复杂度= o(n),其中n是字符串的长度

  • space complectity = o(no_of_chcharacters),其中no_of_of_characters是256


最终代码

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

static void print_dup(const char *str)
{
    size_t *count = calloc(1 << CHAR_BIT, sizeof(size_t));
    for(size_t i = 0; str[i]; i++)
    {
        count[(unsigned char)str[i]]++;
    }
    for (size_t i = 0; i < (1 << CHAR_BIT); i++)
    {
        if(count[i] > 1)
        {
            printf("`%c`, count = %zu\n", i, count[i]);
        }
    }
    free(count);
}

int main(void) {
    char str[51] = {};
    puts("Enter string:");
    if (scanf("%50s", str) != 1)
    {
        perror("bad input");
        return EXIT_FAILURE;
    }
    print_dup(str);
    return EXIT_SUCCESS;
}

Points to know

  • You don't need to pass the address of the variable str to scanf()
  • Don't use "%s", use "%<WIDTH>s", to avoid buffer-overflow
  • Always check whether scanf() conversion was successful or not, by checking its return value
  • Always use size_t to iterator over any array
  • i < strlen(str), makes the loop's time complexity O(n3), instead of O(n2), which also isn't very good you should check whether str[i] != 0. But, many modern compilers of C will optimize it by the way.
  • #include <Stdio.h> it is very wrong, stdio.h != Stdio.h
  • Call to printf() can be optimized using puts() and putc() without any special formatting, here also modern compiler can optimize it
  • while(str[k] != '\0')){ has a bracket (')')
  • Initialize your variable str using {}, this will assign 0 to all the elements of str

Better Implementation

My implementation for this problem is that create a list of character (256 max) with 0 initialized, and then add 1 to ASCII value of the character (from str) in that list. After that print those character whose value was greater than 1.

  • Time Complexity = O(n), where n is the length of the string

  • Space Complexity = O(NO_OF_CHARACTERS), where NO_OF_CHARACTERS is 256


Final Code

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

static void print_dup(const char *str)
{
    size_t *count = calloc(1 << CHAR_BIT, sizeof(size_t));
    for(size_t i = 0; str[i]; i++)
    {
        count[(unsigned char)str[i]]++;
    }
    for (size_t i = 0; i < (1 << CHAR_BIT); i++)
    {
        if(count[i] > 1)
        {
            printf("`%c`, count = %zu\n", i, count[i]);
        }
    }
    free(count);
}

int main(void) {
    char str[51] = {};
    puts("Enter string:");
    if (scanf("%50s", str) != 1)
    {
        perror("bad input");
        return EXIT_FAILURE;
    }
    print_dup(str);
    return EXIT_SUCCESS;
}
嘦怹 2025-01-29 09:43:36

用英语阅读您的代码:仅增量变量k如果索引的字符k等于index i的字符。对于任何具有不同前两个字符的字符串,您将遇到无限循环:char在索引i == 0在索引上不等于char k == 1,因此k未递增和,而(str [k]!= 0)永远。

Read your code in English: You only increment variable k if character at index k is equal to character at index i. For any string that has different first two characters you will encounter infinite loop: char at index i==0 is not equal to char at index k==1, so k is not incremented and while(str[k]!=0) loops forever.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文