1

I need to get the first item from an string arrays in C, this is my code:

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

int main() {
    char *codes[16] = {
        "VVVV", "VVVB", "VVBV", "VVBB", "VBVV", "VBVB", "VBBV", "VBBB",
        "BVVV", "BVVB", "BVBV", "BVBB", "BBVV", "BBVB", "BBBV", "BBBB"
    };
    char code[4];
    int ret = 0;
    int j = 0;

    printf("Enter code to search: ");
    scanf("%s", code);
    
    for (j = 0; j < 16; j++) {
        printf("\ncode to search is:  %s, j value: %d, codes[j]: %s",
               code, j, codes[j]);  
        ret = strcmp(code, codes[j]);
        if (ret == 0) {
            printf("\nValue of index: %d\n", j);
        }
    }
}

When I enter the first code to search (VVVV) I get a void value in position 0, and It doesn't return the index 0. Another values works but the first doesn't.

This is the output:

Enter code to search: VVVV

code to search is:  VVVV, j value: 0, codes[j]: 
code to search is:  VVVV, j value: 1, codes[j]: VVVB
code to search is:  VVVV, j value: 2, codes[j]: VVBV
code to search is:  VVVV, j value: 3, codes[j]: VVBB
code to search is:  VVVV, j value: 4, codes[j]: VBVV
code to search is:  VVVV, j value: 5, codes[j]: VBVB
code to search is:  VVVV, j value: 6, codes[j]: VBBV
code to search is:  VVVV, j value: 7, codes[j]: VBBB
code to search is:  VVVV, j value: 8, codes[j]: BVVV
code to search is:  VVVV, j value: 9, codes[j]: BVVB
code to search is:  VVVV, j value: 10, codes[j]: BVBV
code to search is:  VVVV, j value: 11, codes[j]: BVBB
code to search is:  VVVV, j value: 12, codes[j]: BBVV
code to search is:  VVVV, j value: 13, codes[j]: BBVB
code to search is:  VVVV, j value: 14, codes[j]: BBBV
code to search is:  VVVV, j value: 15, codes[j]: BBBB

What could be wrong?

1
  • 4
    C strings have a zero byte at the end known as the NUL terminator. So an array of four bytes (char code[4]) is not big enough to hold a string like VVVV because there's no room for the NUL terminator. So after you type VVVV to the scanf, you have a buffer overrun and undefined behavior. After that, anything can happen... Commented Jul 14, 2022 at 2:41

1 Answer 1

1

Your code has a buffer overflow, which is a very dangerous kind of undefined behaviour.

The following line

char code[4];

declares an array of char that can hold up to 3 characters plus a null-terminator character, which add up to 4 characters total. This is because C strings are null-terminated.

When you attempt to scan a 4 character string (don't forget the 5th \0 that's added automatically) into a 3 character buffer (plus the 4th \0), your code overflows. Therefore, you need to change the line above to

char code[5];

That said, your code is far from being trouble-safe. And yes, I mean that scanf() call. I suggest you read this post as it explains the pitfalls of that function, and provides alternative solutions.

Here is a better version of your code:

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

int main(void)
{
    char *codes[] = { // Let your array be flexible in case you want to add to it later.
        "VVVV", "VVVB", "VVBV", "VVBB",
        "VBVV", "VBVB", "VBBV", "VBBB",
        "BVVV", "BVVB", "BVBV", "BVBB",
        "BBVV", "BBVB", "BBBV", "BBBB"
    };
    
    // Computes the size (number of items) of an array object.
    // Doesn't work for pointers to arrays.
    // Also, use size_t as it's the appropriate type for sizes.
    size_t ncodes = sizeof(codes) / sizeof(codes[0]);
    
    char code[5]; // <-- 4 characters + \0
    printf("Enter code to search: ");
    
    if (scanf(" %4[^\n]", code) != 1) {
        printf("Error: scanf() failed.\n");
        return 1;
    }
    
    bool found = false;
    
    for(size_t j = 0; j < ncodes; ++j) {
        if (strcmp(code, codes[j]) == 0) {
            printf("Code found at index: %zu\n", j);
            found = true;
            break; // Stop looping when you find the first occurence
        }
    }
    
    if (!found) {
        printf("Code %s not found.\n", code);
    }
}
Sign up to request clarification or add additional context in comments.

6 Comments

Answer of Zakk works for me, thanks.
Format %ld is incorrect for a size_t: you should use %zu
Nitpicking: you should test the return value of scanf() to avoid undefined behavior if stdin is redirected from an empty file.
@chqrlie ... or from a file that begins with '\n'. Zakk, suggest " %4[^\n]" (add space) to consume white-space.
Your explanation Computes the size (number of items) of a STATIC array. is somewhat confusing: codes is not a static array, it has automatic storage. You might use the term array object as opposed to pointer to an array and make it explicit that sizeof(codes) / sizeof(codes[0]) would not work if codes were a pointer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.