YellowBird
YellowBird

Reputation: 25

Loop doesn't end

int main(void){

    int range = 0, i = 0;

    printf("Enter the number of digits of the number: ");
    scanf("%d", &range);

    int a[range];
    int b[range];

    printf("Enter the number: ");
    for(i = 0; i < range; i++){
            scanf("%1d", &a[i]);
    }

    replace(a, b, range);

    swap(&b[0],&b[range]);

    printf("Output: ");
    for(i = range; i > 0; i--){
            printf("%d", b[i]);
    }

    return 0;
}

void replace(int *a, int *b, int n){
    int *p;
    int temp;

    for(p = a; p < a + n; p++){
            temp = ((*p + 6) % 10) / 10;
            p = b;
            *p = temp;

    }
 }

  void swap(int *p, int *q)
 {
    int temp;

    temp = *p;
    *p = *q;
    *q = temp;
 }

My problem is with the first for loop, the loop seems to just keep taking in input and doesn't end. I tried putting a print statement before the replace method and it didn't print so I knew the problem was with the for loop. How do I fix this issue?

Upvotes: 0

Views: 342

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 755064

The replace() function is a disaster

You've now posted the replace function and it is a disaster.

void replace(int *a, int *b, int n)
{
    int *p;
    int temp;

    for (p = a; p < a + n; p++)
    {
        temp = ((*p + 6) % 10) / 10;
        p = b;
        *p = temp;
    }
}

You attempt to iterate over the array a by making p point to each element in turn. But you then, in the body of the loop, assign b to p, which places it outside the array a, which means all bets are off. It's not clear whether b is less than a + n or not — it simply isn't defined. But given that you get an infinite loop, it probably is, so your code goes reading from and writing to the same couple of locations over and over (b[0], b[1]) and p never progresses nearer to a + n.

A simple fix uses indexes:

void replace(int *a, int *b, int n)
{
    for (int i = 0; i < n; i++)
        b[i] = ((a[i] + 6) % 10) / 10;
}

If you want to use pointers, then:

void replace(int *a, int *b, int n)
{
    for (int *p = a; p < a + n; p++)
        *b++ = ((*p + 6) % 10) / 10;
}

Note that the expression evaluates to zero. The modulo 10 operation produces a value in the range 0..9 (or -9..+9), and that divided by 10 is always 0. You'll need to work on that expression.

The call to swap() is broken

You have:

swap(&b[0], &b[range]);

This definitely accesses data out of the bounds of the b array. To be safe, you need to use:

swap(&b[0], &b[range-1]);

Your output loop is broken

You have:

printf("Output: ");
for(i = range; i > 0; i--){
        printf("%d", b[i]);
}

You need to avoid accessing b[range] again, and you need to output a newline at the end:

printf("Output: ");
for (i = range; i > 0; i--)
        printf("%d", b[i-1]);
putchar('\n');

The input code works

The input code works, as demonstrated by this minimal adaptation of what you've got:

#include <stdio.h>

int main(void)
{
    int range = 0, i = 0;

    printf("Enter the number of digits in the number: ");
    if (scanf("%d", &range) != 1)
    {
        fprintf(stderr, "Oops 1\n");
        return 1;
    }
    printf("Number of digits: %d\n", range);

    int a[range];

    printf("Enter the number: ");
    for (i = 0; i < range; i++)
    {
        if (scanf("%1d", &a[i]) != 1)
        {
            fprintf(stderr, "Oops 2\n");
            return 2;
        }
        printf("Digit %d: %d\n", i, a[i]);
    }

    printf("Reversed input: ");
    for (i = range; i > 0; i--)
        printf("%2d", a[i-1]);
    putchar('\n');

    return 0;
}

The 'reversed input' loop is an adaptation of the 'output' loop in the question — bug-fixed to avoid accessing the array out of bounds, and using a instead of b. The error messages are very uninformative (not suitable for production work), but they're adequate to identify which statement caused an error while you're debugging.

Example run:

$ ./example-input
Enter the number of digits in the number: 12
Number of digits: 12
Enter the number: 1234 5678 9101112
Digit 0: 1
Digit 1: 2
Digit 2: 3
Digit 3: 4
Digit 4: 5
Digit 5: 6
Digit 6: 7
Digit 7: 8
Digit 8: 9
Digit 9: 1
Digit 10: 0
Digit 11: 1
Reversed input:  1 0 1 9 8 7 6 5 4 3 2 1
$

Now, adapt this into your program and see where the problem really is.


Working code

#include <stdio.h>

static void swap(int *a, int *b);
static void replace(int *a, int *b, int n);

int main(void)
{
    int range = 0, i = 0;

    printf("Enter the number of digits in the number: ");
    if (scanf("%d", &range) != 1)
    {
        fprintf(stderr, "Oops!\n");
        return 1;
    }
    printf("Number of digits: %d\n", range);

    int a[range];
    int b[range];

    printf("Enter the number: ");
    for (i = 0; i < range; i++)
    {
        if (scanf("%1d", &a[i]) != 1)
        {
            fprintf(stderr, "Oops 2\n");
            return 2;
        }
        printf("Digit %d: %d\n", i, a[i]);
    }

    printf("Reversed input: ");
    for (i = range; i > 0; i--)
        printf("%2d", a[i-1]);
    putchar('\n');

    replace(a, b, range);
    swap(&b[0], &b[range-1]);

    printf("Output: ");
    for (i = range; i > 0; i--)
        printf("%2d", b[i-1]);
    putchar('\n');

    return 0;
}

static void swap(int *p, int *q)
{
    int t = *p;
    *p = *q;
    *q = t;
}

static void replace(int *a, int *b, int n)
{
    for (int *p = a; p < a + n; p++)
        *b++ = ((*p + 6) % 10);
}

Example output

$ ./example-input
Enter the number of digits in the number: 9
Number of digits: 9
Enter the number: 123 456 789
Digit 0: 1
Digit 1: 2
Digit 2: 3
Digit 3: 4
Digit 4: 5
Digit 5: 6
Digit 6: 7
Digit 7: 8
Digit 8: 9
Reversed input:  9 8 7 6 5 4 3 2 1
Output:  7 4 3 2 1 0 9 8 5
$

Upvotes: 6

Related Questions