Iterate Over Array in Another Function in C

Viewed 142

I have an array of unknown size populated while reading the file in main function. I would like to write another function that iterates over this array, compare strings and return index of requested string.

However, I seem cannot iterate over all array and getting only the first element.

When trying to print an element found in the array (from findIndex), I get the following error: format specifies type 'char *' but the argument has type 'char' and I need to change to %c in the printf, as I understand this is because I'm iterating over the first item in the array, but not the whole array.

Is this because I'm creating an array in the main function as char *items[MAXKEY]? How can I fix the issue and return index of a requested string from a function?

int findIndex(int index, char *array, char *item) {

    for (int i = 0; i < index; i++) {

        if (strcmp(&array[i], item) == 0) {

            printf("%s\n", array[i]);  // rising an error format specifies type 'char *' but the argument has type 'char'
           // return i;                // does not return anything 
        }
    }
    return 0;
}

int main () {
    
    FILE *file; 

    char *items[MAXKEY];
    char token[MAXKEY];
    
    int index = 0;

    // adding elements to the array 
    while (fscanf(file, "%s", &token[0]) != EOF) {
        items[index] = malloc(strlen(token) + 1);
        strcpy(items[index], token);
        index++; 
    }
    return 0; 
}
2 Answers

The parameter array of your function has an incorrect type.

In this call of printf

printf("%s\n", array[i]);

the argument array[i] has the type char. So you may not use the conversion specifier s with an object of the type char.

Also 0 is a valid index. So this return statement

return 0;

will confuse the caller of the function because it can mean that the string is found and at the same time that the string is not found.

The function can be declared and defined the following way

int findIndex( char **array, int n, const char *item ) 
{
    int i = 0;

    while ( i < n && strcmp( array[i], item ) != 0 ) i++;

    return i;
}

though for indices and sizes of arrays it is much better to use the unsigned integer type size_t instead of the type int.

And in main the function can be called like

int pos = findIndex( items, index, some_string );

where some_string is a string that should be searched in the array.

If the string is not found in the array then pos will be equal to the current actual size of the array that is to index,

So you can write for example in main after the call

if ( pos == index )
{
   puts( "The string is not present in the array." );
}

There are some problems in your code:

  • in main(), you define a char array of size MAXKEY, for up to MAXKEY-1 characters, but you also define an array of char pointers with the same size. Is the number of strings the same as the maximum size of a string?
  • the prototype for find_index() in inconsistent with your goal: you should declare the array of strings as char **array or char *array[].
  • returning 0 for failure is also a problem as this would be the same value if the string is found at index 0. Returning -1 for failure seems more reasonable.
  • file is not open, nor closed.
  • you should use strdup() instead of manually allocating the memory and copying the string, albeit you correctly allocated one extra byte for the null terminator.

Here is a modified version:

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

int findIndex(char *array[], int count, const char *item) {
    for (int i = 0; i < count; i++) {
        if (strcmp(array[i], item) == 0) {
            return i;
        }
    }
    return -1;
}

#define MAXKEY 1000  // maximum number of keys

int main() {
    FILE *file; 
    char *items[MAXKEY];
    char token[100];
    int count;

    file = fopen("keys.txt", "r");
    if (file == NULL) {
        printf("cannot open keys.txt\n");
        return 1;
    }
    // adding elements to the array 
    for (count = 0; count < MAXKEY && fscanf(file, "%99s", token) == 1; count++) {
        items[count] = strdup(token);
        if (items[count] == NULL)
            break;
    }
    fclose(file);
    printf("Enter key: ");
    if (scanf("%99s", token) == 1) {
        int index = find_index(items, count, token);
        if (index < 0) {
            printf("Key %s not found\n", token);
        } else {
            printf("Key %s found at index %d\n", token, index);
        }
    }
    while (count --> 0) {
        free(items[count]);
    }
    return 0; 
}
Related