Home > Blockchain >  atof() removes one character at the end
atof() removes one character at the end

Time:08-12

I am aware of the low quality of the code, I am a beginner to programming in C. The following program attemps to receive input from the user, turn it into tokens and then perform basic math with them. If the input exceeds 8 characters: ('256 256'), it fails to properly return a correct result, instead 256 256 is interpreted as `256 25. It's been hours and hours of debugging and I cannot pinpoint the error.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define MAX 1024

typedef struct tokenReturn {
    int arrayMembers;
    char* tokens[];
}
t_return;

t_return *getAndTokenize(char* delim) {
    // Get user input and store it as a string literal.
    char* input = malloc(1024);
    char lit_in[MAX];
    
    if (fgets(input, MAX, stdin) == NULL) {
        perror("Error: ");
        exit(EXIT_FAILURE);
    }

    strncpy(lit_in, input, MAX);
    free(input);
    // Create the return structure to return not only the char* array but the max index as well.
    t_return *return_struc = malloc(sizeof(t_return)   MAX);
    if (return_struc == NULL) {
        puts("Allocation error");
        perror("Error");
        exit(EXIT_FAILURE);
    }
    
    // Assign first member due to the weird behaviour the strtok function has.
    char *token = strtok(lit_in, delim);
    return_struc->tokens[0] = token;
    
    int i = 1; // We have to start at one since we already have one token stored in the array
    while (true) 
    {
        // Check to see if all the tokens have been obtained.
        if((token = strtok(NULL, delim)) == NULL) {
            break;
        }
        return_struc->tokens[i] = token;
        i  ;
    }
    // Assign i to arrayMembers so that we can determine array length.
    return_struc->arrayMembers = i;
    
    return return_struc;
}

float sum(float x, float y) {
    return x   y;
}

float multiply(float x, float y) {
    return x * y;
}

float subs(float x, float y) {
    return x - y;
}

float division(float x, float y) {
    return x / y;
}

int main(void) {
    // Init
    printf("Operation: ");
    t_return* tokens = getAndTokenize(" ");
    float a = atof(tokens->tokens[0]);
    char symbol = tokens->tokens[1][0];
    float b = atof(tokens->tokens[2]);
    float result;

    // Check for the operation being done
    switch (symbol) {
        case ' ':
            result = sum( a, b );
            break;
        
        case '-':
            result = subs(a, b);
            break;
        
        case '/':
            result = division( a, b ); 
            break;
        
        case '*':
            result = multiply( a, b );
            break;
        
        default:
            puts("Operation not recognized!");
            exit(EXIT_FAILURE);
    }

    printf("Result is: %.3lf\n", result);
    exit(EXIT_SUCCESS);
}

CodePudding user response:

getAndTokenize copies the input into lit_in, which is an automatic object inside getAndTokenize. Once getAndTokenize returns, the memory for lit_in is no longer reserved, and the pointers you put into the t_return structure pointing into lit_in are no longer valid. Some of the other code in main does things that reuse that memory for other purposes. Change getAndTokenize to keep the input in an allocated buffer that is not freed until the program is done using the data in it.

  • Related