ehem
ehem

Reputation: 70

C - Print Array

I am trying to print the elements that I add in an array in real time .

Everything seems to work fine but

for example

I add the numbers 1 2 3

But the resuls are : 9966656 2686588 1 2 3

I don't know why It prints 9966656 2686588 as well and not only 1 2 3

    int numbers[100] , c , x;
    char answer;
    puts("Please insert a value");

GO:
    scanf("%d", &numbers[c]);
    getchar();
    puts("Do you want to add another value? y/n");
    scanf("%c",&answer);
    if (answer == 'y') {
        c = c + 1;
        puts("Please insert another value");
        goto GO;
    } else {
        x = c;

        for (c = 0; c < x + 1; c++) {
            printf("%d ",numbers[c]);
        }
    }

*=====================

Let me know if you haven't understand something*

Upvotes: 0

Views: 200

Answers (2)

David C. Rankin
David C. Rankin

Reputation: 84521

There are several issues you need to address. All of them would have been spelled out for your if you would have compiled with Warnings Enabled (e.g. add -Wall -Wextra to your compile string.) For example:

$ gcc -Wall -Wextra -o bin/go go.c

go.c: In function ‘main’:
go.c:17:5: warning: format ‘%c’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[30]’ [-Wformat=]
 scanf("%c",&answer);
 ^
go.c:18:15: warning: comparison between pointer and integer [enabled by default]
 if(answer == 'y')

If you address each warning until your code compiles without a warning, you then run into your primary problem:

for(c = 0; c < x + 1; c++)

x + 1 causes your loop to read beyond the end of your data. Since you did NOT initialize numbers, it is reading garbage values that were there by default. That is another good lesson: Always initialize your variables.

You will also run into problem with the way you are managing x and c. c should only be updated on successful conversion of a decimal from the user as read by scanf. scanf provides, as it's return, the number of successful conversions. You need to use the return to check for a valid decimal entered by the users, and then update c only upon a successful conversion (not as the result of the user entering y/n.

Cleaning things up a bit, you would be better served by a slight rearrangement of your logic to something similar to:

#include <stdio.h>

int main (void) {

    int numbers[100] = { 0 };
    int c = 0;
    int i = 0;
    char answer[30] = { 0 };

    printf (" Please insert a value: ");

GO:

    if (scanf ("%d", &numbers[c]) == 1)
        c++;
    getchar ();
    printf (" Do you want to add another value (y/n)? ");
    scanf ("%c", answer);
    if (*answer == 'y') {
        printf (" Please insert another value: ");
        goto GO;
    }

    for (i = 0; i < c; i++) {
        printf (" number[%2d] : %d\n", i, numbers[i]);
    }

    return 0;
}

Output

$ ./bin/go
 Please insert a value: 10
 Do you want to add another value (y/n)? y
 Please insert another value: 11
 Do you want to add another value (y/n)? y
 Please insert another value: 12
 Do you want to add another value (y/n)? n
 number[ 0] : 10
 number[ 1] : 11
 number[ 2] : 12

(note: I changed x to i - just felt more normal to iterate i)

Upvotes: 1

Alex Lop.
Alex Lop.

Reputation: 6875

The behavior is UNDEFINED since c is not initialized and you use it as "index" (&numbers[c]). This might also cause to segmentation fault and even act as you expect.

What you need to do is to set c to 0 at the very beginning.

Also please try avoiding goto unless there is a real and justified reason to use it.

Upvotes: 0

Related Questions