Home > Software engineering >  Why is this code producing an infinite loop?
Why is this code producing an infinite loop?

Time:04-19

#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.

CodePudding user response:

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("Ps", str) != 1)
    {
        perror("bad input");
        return EXIT_FAILURE;
    }
    print_dup(str);
    return EXIT_SUCCESS;
}

CodePudding user response:

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.

  • Related