Search code examples
cc89

C90: While loop function condition always met


First question main program in file set_my.c You must write a program that accepts as input a list of integer values ​​of type int. From this list of values you have to build a group. The program must receive the list of values ​​from the user, build the group from them, and finally print the the members of the group in the order of their arrival.Normality of the input can be assumed, but there may be values ​​that repeat more than once in the input list For such a value (which appears more than once in the input), its first appearance determines its position in printed output.The number of members in the group is not limited and formatthe realloc function must be used.The number of values ​​in the input is also not limited. The input can be in multiple lines, and each line can appear an unlimited number of entries.

The end of input will beidentified by the EOF value returned from a function in the standard library, through which the input is performed (in input from the keyboard, EOF can be inserted by typing d-ctrl at the beginning of a new line). Input example:

13 13 13 45 -9 -9 -9 18 18 18 3 4 55 45 66 13 66

For this input, the output would be:

13 45 -9 18 3 4 55 66

The output contains only the unique values that appeared in the input, in the order of their first appearance.h

The duplicate values are removed.

You are asked to write two functions:

set_get - This function reads input from the user and stores it in a set.

set_print - This function prints the elements of the set in the required order and format.

Here will be my code what I have done so far.

setSize setArr;
char* input; /*problem with pointing char pointer type directly*/
int prev, size, inputN, count;
int* set;
bool checkMinus;
checkMinus= true;
prev = DEFULT;/*initialze to DEFULT */
set  = NULL; /* initialize set to NULL */
size = 0; /* size of set*/
count = 0;/* number of elements in set*/
inputN; /* transformed from char type to integar type*/
input = malloc(sizeof(char)*2);
input[1] = '\0';
set = (int *) malloc(sizeof(int));

/* prompt user for input */
printf("Enter integers to add to set, one at a time or space between each integers.\n");
printf("End input with Ctrl-D (EOF).\n");
/* loop to read input until EOF is reached */
while (1)
{
    *input = getchar();
    if (feof(stdin)) {
        break;
    }
    
    if (input == ' ' && !checkMinus) { /* initializing check back to true conditons*/
        checkMinus = true; 
    }
                    
    if (!checkMinus && input == '-'){/* check for correction of minus or pluses */
        printf("Please insert valid input requested "
               "(not allowed to have plus or twice in the same number minus).\n");
        exit(1);
    }
                
    if ((*input <'0' || *input > '9') && *input != ' ' && *input != '-'  && *input != '\n' && *input != EOF ) {
        printf("Please insert valid input requested( phrase plus sign was included ).\n");
        exit(1);
    }
                    
    inputN = atoi(input);/*transforming to integar*/

    if (inputN != prev) {
        prev = inputN;/* we will assign new value to prev */
        set = (int *) realloc(set,SIZE_ENLARGE(size++)); /*resize set*/

        if (set == NULL) { /*check if realloc failed*/
            printf("Error: could not allocate memory.\n");
            exit(1);
        }
                        
        set[count++] = inputN; /* add input to set */
    }
}

Debugging tried to add couple more conditions didn't achieve anything much, but while debugging i found out that the condition is always met no matter what .I had a whole different code, but I couldn't figure out how to fix it and begin a new one from the begginging, but now I have a weird bug where one codition

if  ((*input <'0' || *input > '9') && *input != ' ' && *input != '-'  && *input != '\n' && *input != EOF )

is always met, and I got no idea how to fix it, its in the while loop I honestly got no idea what causes this or how to fix it, please help me out I been working on this so hard.

I have tried debugging and found out that I couldn't get past that condition (*input <'0' || *input > '9') && *input != ' ' && *input != '-' && *input != '\n' && *input != EOF )


Solution

  • You posted your assignment and a snippet of code which has issues:

    1. You should point out that "unlimited" in the problem description is flawed. You are limited by virtual memory or at least disk size. Also sets, by definition are unsorted, so they should call it something else.
    2. header files are missing
    3. snippet of code not even in a function
    4. setSize is not defined
    5. DEFAULT is not defined
    6. inputN; doesn't do anything; supposed to be an initialization?
    7. input should be an int when used to store data from getchar().
    8. Not sure why you are dynamically allocating input() when it's a fixed array of size 2 (and really you just need an int).
    9. input == ' ' compares a pointer to an integer constant which is not what you want.
    10. Assign the value from realloc() to a temporary variable, otherwise you leak memory on failure. In the code below caller should handle a NULL return value.
    11. Don't cast void *.
    12. Prefer initializing variables when you declare them. It's less duplication and you eliminate the error case of using an uninitialized variable.
    13. Prefer to minimize scope of variables
    14. Use more functions to structure your code. For instance, if you can't use scanf() in this assignment, you now know that you just need to write your own implementation of reading an integer from stdin. This function may fail.
    #include <stdbool.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    struct set {
        int *data;
        size_t n;
    };
    
    struct set *set_add(struct set *s, int v) {
        for(size_t i = 0; i < s->n; i++)
            if(s->data[i] == v)
                return s;
        int *tmp = realloc(s->data, sizeof(s->data) * (s->n + 1));
        if(!tmp)
            return NULL;
        s->data = tmp;
        s->data[s->n++] = v;
        return s;
    }
    
    void set_print(const struct set *s) {
        for(size_t i = 0; i < s->n; i++) {
            printf("%d%s", s->data[i], i + 1 == s->n ? "\n" : " ");
        }
    }
    
    struct set *set_get(struct set *s) {
        for(;;) {
            int v;
            if(scanf("%d", &v) != 1)
                break;
            set_add(s, v);
        }
        return s;
    }
    
    int main() {
        struct set *s = &(struct set) { 0 };
        set_get(s);
        set_print(s);
    }
    

    and example session:

    13 13 13 45 -9 -9 -9 18 18 18 3 4 55 45 66 13 66
    13 45 -9 18 3 4 55 66