CameFromSpace
CameFromSpace

Reputation: 123

atoi() not working with char array

I am learning C and I am trying to find how to much things with a database that I have made with char arrays.

I know atoi works with strings, but I cannot understand the difference between string and char array declaration (i understand strings have also a char with '/0').

It creates a warning when compiling [Warning] initialization makes integer from pointer without a cast at the line int w = LoggersID[j];

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

int main()
{
    // Logger ID Database
    char LoggersID[50][2];
    strcpy(LoggersID[1], "A");
    strcpy(LoggersID[2], "B");
    strcpy(LoggersID[3], "C");
    strcpy(LoggersID[4], "D");
    strcpy(LoggersID[5], "E");
    strcpy(LoggersID[6], "F");
    strcpy(LoggersID[7], "G");
    strcpy(LoggersID[8], "H");
    strcpy(LoggersID[9], "I");
    strcpy(LoggersID[10], "J");
    strcpy(LoggersID[11], "K");
    strcpy(LoggersID[12], "L");
    strcpy(LoggersID[13], "M");
    strcpy(LoggersID[14], "N");
    strcpy(LoggersID[15], "O");
    strcpy(LoggersID[16], "P");
    strcpy(LoggersID[17], "Q");
    strcpy(LoggersID[18], "R");
    strcpy(LoggersID[19], "S");
    strcpy(LoggersID[10], "T");
    strcpy(LoggersID[21], "1");
    strcpy(LoggersID[22], "2");
    strcpy(LoggersID[23], "3");
    strcpy(LoggersID[24], "4");
    strcpy(LoggersID[25], "5");
    strcpy(LoggersID[26], "6");
    strcpy(LoggersID[27], "7");
    strcpy(LoggersID[28], "8");
    strcpy(LoggersID[29], "9");
    strcpy(LoggersID[30], "10");


    printf("Lets start!\n");


    for (int i = 65; i < 86; i++)
    {
        for (int j = 1; j < 31; j++)
        {
            int w = atoi(LoggersID[j]);
            if (w == i)
            {
                printf("\nYou matched %s with %d", LoggersID[j], i);
            }
        }
    }

    for (int i = 1; i < 11; i++)
    {
        for (int j = 1; j < 31; j++)
        {
            int w = LoggersID[j];
            if (w == i)
            {
                printf("\nYou matched %s with %d", LoggersID[j], i);
            }
        }
    }
    printf("\nProgram finished!");
    getchar();
    return 0;
}

When I run it I get

Lets start!

Program finished!

instead of matching!

Upvotes: 0

Views: 4417

Answers (3)

chqrlie
chqrlie

Reputation: 144770

Your code has some problems:

  • arrays are 0 based in C: the first element is at offset 0.

  • the array elements should have at least 3 characters to accommodate for the null terminator for strings of 2 characters such as "10".

  • you could use an initializer for the array instead of tediously initializing the elements with strcpy().

  • converting the array elements from a string to a numeric value is done either by calling atoi() or strtol() to convert the string encoded as digits, or by reading the value of the first character with int w = LoggersId[i][0];. Converting the address of the element to an int is meaningless. The compiler issues a warning:

    [Warning] initialization makes integer from pointer without a cast
        at the line int w = LoggersID[j];
    

    Such warnings indicate programming errors and should be considered fatal. you can configure the compiler to help you avoid such mistakes with extra options on the command line, such as gcc -Wall -Werror or clang -Weverything -Werror.

Here is a modified version where you will see the matches for the 2 approaches:

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

int main(void) {
    // Logger ID Database
    char LoggersID[30][3] = {
        "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
        "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
        "1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
    };

    printf("Lets start!\n");
    for (int i = 1; i < 11; i++) {
        for (int j = 0; j < 30; j++) {
            int w = atoi(LoggersID[j]);
            if (w == i) {
                printf("You matched LoggersID[%d] = \"%s\" with %d\n",
                       j, LoggersID[j], i);
            }
        }
    }

    for (int i = 65; i < 85; i++) {
        for (int j = 0; j < 30; j++) {
            int w = LoggersID[j][0];
            if (w == i) {
                printf("You matched LoggersID[%d] = \"%s\" with %d (%c)\n",
                       j, LoggersID[j], i, i);
            }
        }
    }
    printf("\nProgram finished!");
    getchar();
    return 0;
}

Upvotes: 2

Jabberwocky
Jabberwocky

Reputation: 50774

There are 3 issues:


Replace char LoggersID[50][2]; with char LoggersID[50][3];

Following line copies 3 chars into a 2 char buffer. The string literal "10" takes up 3 chars because of the NUL Terminator.

strcpy(LoggersID[30], "10");

Replace int w = LoggersID[j]; with int w = atoi(LoggersID[j]);.

LoggersID[j] is a char* (pointer to char) and not an int, therefore you need to convert the string to an int using the atoi function.

That's why you get the warning initialization makes integer from pointer without a cast at the line int w = LoggersID[j]. This warning is actually most of the time an error.


You certainly have a typo here:

Replace strcpy(LoggersID[10], "T"); by strcpy(LoggersID[20], "T");


By the way the 30 strcpy lines could be replaced by about 6 lines of code.

Upvotes: 2

anil
anil

Reputation: 158

atoi() works only for numbers in string like this "123". It will return integer value for this string. As soon as it detects any character other than 0-9, it terminates the process. So in loop, you are not checking for values 1 to 10.

  int w = atoi(LoggersID[j]);
        if (w == i)

So it is not printing anything. Hope this helps.

Upvotes: 0

Related Questions