Home > Enterprise >  Allows the user to change the value of "5" inside array function
Allows the user to change the value of "5" inside array function

Time:11-26

As my title suggests, I am a beginner who is playing a bit with arrays. Although I try to do my best, I am not able to properly change the values inside an array? As you can see, only the last 5 digits are correct in array but not the first 3? Why is that the case? I will post my code below so all of you can see what i mean:

#include <stdio.h>
#include <stdlib.h>
#define MAX_ARRAY 8
void input_array(char anumber[MAX_ARRAY])
{
    printf("\n\nPlease insert new data to the 1st array with value 5: ");
    fgets(&anumber[0], MAX_ARRAY, stdin);     
    long ret = strtol(&anumber[0], NULL, 10); // Converts char to int
    printf("Converting char anumber = %d to int ret = %d\n", anumber[0], ret);
    printf("\n(Array after): ");
    for (int i = 0; i < MAX_ARRAY;   i)
    {
        printf("(%d) ", anumber[i]);
    }
}
int main(void)
{
    char arr[MAX_ARRAY] = {5, 8, 2, 9, 1, 7, 4, 3};
    printf("(Array before): ");
    for (int i = 0; i < MAX_ARRAY;   i)
    {
        printf("(%d) ", arr[i]);
    }
    input_array(arr); // Function that lets the user change value of "5" inside the array
    return 0;
}

Output from this code if I as user enter value "3" is:

(Array before): (5) (8) (2) (9) (1) (7) (4) (3) 

Please insert new data to the 1st array with value 5: 3
Converting char anumber = 51 to int ret = 3

(Array after): (51) (10) (0) (9) (1) (7) (4) (3)

CodePudding user response:

Opening remark:

The line

long ret = strtol(&anumber[0], NULL, 10); // Converts char to int

is wrong. In particular, the comment // Converts char to int is wrong. The function strtol will not convert a single character to an int. Instead, it will convert a string (i.e. a sequence of characters) to a long.

In order to convert a single digit character to an int, you can write the following line instead:

int number = anumber[0] - '0';

This is possible because ISO C requires that the character set stores the numbers 0 to 9 sequentially.

What is happening in your program is actually the following:

You are initializing the 8 elements of your array to the following values:

(5) (8) (2) (9) (1) (7) (4) (3) 

Afterwards, you input the string "3\n" from the user using fgets. The corresponding ASCII codes are 51 for the digit '3' and 10 for the newline character '\n'. You overwrite the first two elements of the array with these two values, and the third element with the terminating null character of the string.

That is why the array has the following values after the call to fgets:

(51) (10) (0) (9) (1) (7) (4) (3)

The function fgets overwrites the first 3 elements, but leaves the remaining elements intact.

The correct way to solve the problem is the following:

You seem to only want to overwrite the first element of the array. Therefore, you should not use the array as the direct target of an fgets function call, as that function will always write more than one byte (when using the function properly).

One very simple way of solving the problem would be the following:

void overwrite_first_element_with_input( char arr[MAX_ARRAY] )
{
    //prompt user for input
    printf( "Please enter new data for the first element of the array: " );

    //write input to first element
    if ( scanf( "%hhd", &arr[0] ) != 1 )
    {
        printf( "input error!\n" );
        exit( EXIT_FAILURE );
    }
}

The full program would look like this (with some minor improvements):

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

#define MAX_ARRAY 8

void overwrite_first_element_with_input( char arr[MAX_ARRAY] )
{
    //prompt user for input
    printf( "Please enter new data for the first element of the array: " );

    //write input to first element
    if ( scanf( "%hhd", &arr[0] ) != 1 )
    {
        printf( "input error!\n" );
        exit( EXIT_FAILURE );
    }
}

void print_array( const char arr[MAX_ARRAY], const char *tag )
{
    printf( "%s", tag );

    for ( int i = 0; i < MAX_ARRAY; i   )
    {
        printf( "(%d) ", arr[i] );
    }

    printf( "\n" );
}

int main( void )
{
    char arr[MAX_ARRAY] = {5, 8, 2, 9, 1, 7, 4, 3};

    print_array( arr, "(Array before): " );
    overwrite_first_element_with_input( arr );
    print_array( arr, "(Array after): " );

    return 0;
}

Here is some sample output of the program:

(Array before): (5) (8) (2) (9) (1) (7) (4) (3) 
Please enter new data for the first element of the array: 20
(Array after): (20) (8) (2) (9) (1) (7) (4) (3) 

However, I don't want to encourage you to use scanf instead of fgets and strtol, as scanf has many disadvantages. If you want to solve the problem with fgets and strtol, I would recommend the following code:

void overwrite_first_element_with_input ( char arr[MAX_ARRAY] )
{
    char line[100], *p;
    long ret;

    //prompt user for input
    printf( "Please enter new data for the first element of the array: " );

    //attempt to read one line of input and verify success
    if (
        //verify that fgets was successful
        fgets( line, sizeof line, stdin ) == NULL

        ||

        //verify that input buffer was large enough to store entire line
        strchr( line, '\n' ) == NULL
    )
    {
        printf( "input error!\n" );
        exit( EXIT_FAILURE );
    }

    //attempt to convert input to number
    ret = strtol( line, &p, 10 );
    if ( p == line )
    {
        printf( "conversion failure!\n" );
        exit( EXIT_FAILURE );
    }

    //write the successfully converted number to the array
    arr[0] = ret;
}

Note that you must add #include <string.h> for the code above to work.

CodePudding user response:

hello as i see you tried to save your numeric array in char so it can cause this kind of mistakes .define two variable for characters and another for numbers.

  • Related