user1728737
user1728737

Reputation: 59

Can't get negative inputs set to zero. How can negative arrays get set?

The following code works for all positive inputs correctly but, negative values are bogus. It would work if negative values are set to 0 initially, because they do add. Example at the end.

#include <stdio.h>                                                             /* Necessary header */
#define MAX_RESPONDENTS 6
#define MIN_RESPONSE_VALUE -100                                                /* Abbreviated MiRV */
#define MAX_RESPONSE_VALUE 86                                                   /* Abbreviated MaRV */
#define RESPONSE_VALUE 187                                                      /* Equals |(MiRV)| + or - |(MaRV)| + 1 */
#define STOP 3
#define BREAK 1

int main(void)
{
    CountRating();

    return 0;
}

CountRating()
{
    int ratingCounters, rating[RESPONSE_VALUE] = {0}, Counter, response;

    for (ratingCounters = 0; ratingCounters < MAX_RESPONDENTS;)
    {
        int response = ratingCounters, stop = STOP;
        printf("Enter a integer rating between %d and %d for the product: ", MIN_RESPONSE_VALUE, MAX_RESPONSE_VALUE);
        scanf("%d", &response);

        if (response <= MAX_RESPONSE_VALUE && response >= MIN_RESPONSE_VALUE)
            stop = STOP;
        else
        {
            int stopElse = stop;
            if (stopElse < BREAK)
                break;
            else
            {
                do
                {
                    printf("\nNot within range. Try again.\nYou have %d more attempts before program outputs total:", stop);
                    scanf("%d", &response);
                    printf("\n");
                    --stop;
                    if (stop < BREAK)
                    break;
                } while (response > MAX_RESPONSE_VALUE || response < MIN_RESPONSE_VALUE);
            }   if (stop < BREAK)
                break;
        }
        ++rating[response];
        ++ratingCounters;

    }
    printf("\nRating            Number of Responses\n");
    printf("------            -------------------");

    for (Counter = MAX_RESPONSE_VALUE; Counter >= MIN_RESPONSE_VALUE; --Counter)
    {
        printf("\n%3d%24d", Counter, rating[Counter]);
    }
}

Example Output:

Enter a integer rating between -100 and 86 for the product: 66
Enter a integer rating between -100 and 86 for the product: 66
Enter a integer rating between -100 and 86 for the product: 66
Enter a integer rating between -100 and 86 for the product: 66
Enter a integer rating between -100 and 86 for the product: 66
Enter a integer rating between -100 and 86 for the product: 55

Rating            Number of Responses
------            -------------------
 86                       0
 85                       0
 84                       0
 83                       0
 82                       0
 81                       0
 80                       0
 79                       0
 78                       0
 77                       0
 76                       0
 75                       0
 74                       0
 73                       0
 72                       0
 71                       0
 70                       0
 69                       0
 68                       0
 67                       0
 66                       5
 65                       0
 64                       0
 63                       0
 62                       0
 61                       0
 60                       0
 59                       0
 58                       0
 57                       0
 56                       0
 55                       1
 54                       0
 53                       0
 52                       0
 51                       0
 50                       0
 49                       0
 48                       0
 47                       0
 46                       0
 45                       0
 44                       0
 43                       0
 42                       0
 41                       0
 40                       0
 39                       0
 38                       0
 37                       0
 36                       0
 35                       0
 34                       0
 33                       0
 32                       0
 31                       0
 30                       0
 29                       0
 28                       0
 27                       0
 26                       0
 25                       0
 24                       0
 23                       0
 22                       0
 21                       0
 20                       0
 19                       0
 18                       0
 17                       0
 16                       0
 15                       0
 14                       0
 13                       0
 12                       0
 11                       0
 10                       0
  9                       0
  8                       0
  7                       0
  6                       0
  5                       0
  4                       0
  3                       0
  2                       0
  1                       0
  0                       0
 -1                      55
 -2                 2686244
 -3                 2686244
 -4                      -3
 -5                 4206858
 -6                 4199517
 -7              1965606432
 -8                      -2
 -9              -533773290
-10              1965657301
-11                 2686916
-12              1965975817
-13                 2685900
-14                      28
-15                 2685972
-16                       0
-17                 2686720
-18             -1792050746
-19              1965606432
-20              1966156064
-21                       1
-22              1965606483
-23                 2685944
-24                      17
-25              1965552124
-26                 2685880
-27              1966146752
-28              1965532226
-29                 2685868
-30              1966156064
-31                       1
-32                       0
-33              1966156064
-34                       0
-35                      28
-36                 6105760
-37                       1
-38              1965551966
-39              1965572357
-40                      -2
-41              -533740746
-42              1965657301
-43                 2685928
-44              1966156064
-45                 2685768
-46                      28
-47              1965572357
-48                       0
-49              1966156064
-50                      28
-51             -1792050874
-52              1965572357
-53                       1
-54              1965572401
-55                 2685816
-56                 6097440
-57              1965552169
-58                 2685752
-59                      36
-60              1966146816
-61                       0
-62              1966146816
-63                      36
-64                       0
-65             -1792050942
-66              1965552271
-67              1965552263
-68                 2685756
-69                 6105754
-70                    4104
-71                    4096
-72                 6097428
-73                      36
-74                      -2
-75               358724962
-76              1999401429
-77                 2685928
-78                      -1
-79                 2685472
-80                16777216
-81                 6094848
-82                       1
-83                       0
-84                 6105755
-85                 6105760
-86                 6095044
-87                       8
-88                       2
-89              1999167428
-90                       1
-91                 6095044
-92              -218103565
-93                 2685640
-94              -254549010
-95                       0
-96              1136989510
-97              -503245737
-98                 2752512
-99                 6098688
-100                       0
Process returned 0 (0x0)   execution time : 9.734 s
Press any key to continue.

Upvotes: 0

Views: 143

Answers (5)

user1728737
user1728737

Reputation: 59

Took me a while but I got it. Thanks.

#include <stdio.h>                                                             /* Necessary header */
#define MAX_RESPONDENTS 6
#define MIN_RESPONSE_VALUE -100                                                /* Abbreviated MiRV */
#define MAX_RESPONSE_VALUE 86                                                   /* Abbreviated MaRV */
#define RESPONSE_VALUE 187                                                      /* Equals |(MiRV)| + or - |(MaRV)| + 1 */
#define STOP 3
#define BREAK 1
#define DOUBLE_RESPONSE_VALUE 374

int main(void)
{
    CountRating();

    return 0;
}

CountRating()
{
    int ratingCounters, rating[DOUBLE_RESPONSE_VALUE] = {0}, Counter, response;

    for (ratingCounters = 0; ratingCounters < MAX_RESPONDENTS;)
    {
        int response = ratingCounters, stop = STOP;
        printf("Enter a integer rating between %d and %d for the product: ", MIN_RESPONSE_VALUE, MAX_RESPONSE_VALUE);
        scanf("%d", &response);

        if (response <= MAX_RESPONSE_VALUE && response >= MIN_RESPONSE_VALUE)
            stop = STOP;
        else
        {
            int stopElse = stop;
            if (stopElse < BREAK)
                break;
            else
            {
                do
                {
                    printf("\nNot within range. Try again.\nYou have %d more attempts before program outputs total:", stop);
                    scanf("%d", &response);
                    printf("\n");
                    --stop;
                    if (stop < BREAK)
                    break;
                } while (response > MAX_RESPONSE_VALUE || response < MIN_RESPONSE_VALUE);
            }   if (stop < BREAK)
                break;
        }
        if (response < 0)
            ++rating[response + abs(RESPONSE_VALUE)];
        else
            ++rating[response + abs(RESPONSE_VALUE)];
        ++ratingCounters;

    }
    printf("\nRating            Number of Responses\n");
    printf("------            -------------------");

    for (Counter = MAX_RESPONSE_VALUE; Counter >= MIN_RESPONSE_VALUE; --Counter)
    {
        printf("\n%3d%24d", Counter, rating[Counter + (RESPONSE_VALUE)]);
    }
}

Upvotes: 0

nshy
nshy

Reputation: 1074

Actually the negative index is totally acceptable. The problem is that you index goes into areas outside memory dedicated for array on the stack. Changing rating[-1] you changing your stack outside the array and thus corrupting it. No wonder the values there are not initialized to zero with rating[RESPONSE_VALUE] = {0}, again they are outside the array and show you some data on your stack.

Upvotes: 1

amaurea
amaurea

Reputation: 5067

Your code is assigning to negative indices of an array. This is generally not good - you have only reserved memory from 0:RESPONSE_VALUE-1, writing to anything outside that range will have unpredictable consequences. You have two general options. One is to map your range MIN_RESPONSE_VALUE:MAX_RESPONSE_VALUE to 0:(MAX_RESPONSE_VALUE-MIN_RESPONSE_VALUE). I.e. subtract MIN_RESPONSE_VALUE whenever you index rating:

++rating[response-MIN_RESPONSE_VALUE];

The other is to repoint response, giving it a new zero point. This will save you from having to subtract MIN_RESPONSE_VALUE all the time, but may be confusing to readers:

rating -= MIN_RESPONSE_VALUE;

Do this before the for loop. After doing this, rating[MIN_RESPONSE_VALUE] is a valid index, even though it is negative.

Upvotes: 1

1&#39;&#39;
1&#39;&#39;

Reputation: 27095

Rating is an array of size 187. You're indexing negative values, which means C is accessing memory before the beginning of the array and printing whatever garbage values are stored there. You can only access values between 0 and 186 legally, so you should just add 100 to the index whenever you access and store rating. That way, the number -100 corresponds to index 0, -99 to index 1, etc.

Upvotes: 3

lqs
lqs

Reputation: 1454

The index of an array always starts from zero. You should not pass a negative index for an array. If you want to have negative indexes, add a constant to the index.

In your example code, you can add -MIN_RESPONSE_VALUE to the index, so accessing rating[k - MIN_RESPONSE] if you want to access index k.

Upvotes: 2

Related Questions