Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot copy strings from pointer array with strcpy in C? [duplicate]

I am doing an exercise where a character pointer array is functioning as a way to store words. I do not understand why I cannot use 'strcpy' to copy the word 'hoi' to the second element of the array in the main function. When I compile the code I get the message 'program has stopped working' in CodeBlocks.

The functions 'numberOfWordsInDict' and 'printDict' are working properly.

Thanks in advance.

int numberOfWordsInDict(char **dict)
{
    int i, cnt = 0;
    for(i = 0; i < 10; i++)
    {
        if(dict[i] != NULL)
        {
            cnt++;
        }
    }
    return cnt;
}

void printDict(char **dict)
{
    int i = 0;
    printf("Dictionary:\n");
    if(numberOfWordsInDict(dict) == 0)
    {
        printf("The dictionary is empty.\n");
    } else
    {
        for(i = 0; i < 10; i++)
        {
            printf("- %s\n", dict[i]);
        }
    }
}

int main()
{
    char *dict[10] = {
            "aap", "bro ", "jojo", "koe", "kip", 
            "haha", "hond", "    drop", NULL,NULL};

    char *newWord1 = "hoi";
    printDict(dict);
    strcpy(dict[1], newWord1);
    printDict(dict);

    return 0;
}
like image 853
blabla444 Avatar asked Oct 17 '22 07:10

blabla444


2 Answers

The array dict is an array of pointers to string literals.

In this statement

strcpy(dict[1],newWord1);

you are trying to copy one string literal in another string literal.

String literals are non-modifiable in C and C++. Any attempt to modify a strig literal results in undefined behavior of the program.

From the C Standard (6.4.5 String literals)

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

You should declare a two-dimensional character array if you are going to copy string literals in its elements or a one dimensional array of dynamically allocated character arrays.

The program can look the following way

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

#define N   9

size_t numberOfWordsInDict( char dict[][N] )
{
    size_t n = 0;

    while ( *dict[n] ) ++n;

    return n;
}

void printDict( char dict[][N] )
{
    printf("Dictionary:\n");

    size_t n = numberOfWordsInDict( dict );
    if ( n == 0 )
    {
        printf("The dictionary is empty.\n");
    } 
    else
    {
        for ( size_t i = 0; i < n; i++ )
        {
            printf( "- %s\n", dict[i] );
        }
    }
}

int main(void) 
{
    char dict[10][9] = 
    {
        "aap", "bro ", "jojo", "koe", "kip", "haha", "hond", "    drop"
    };
    char *newWord1 = "hoi";

    printDict(dict);
    strcpy(dict[1], newWord1);
    printDict(dict);

    return 0;
}

The program output is

Dictionary:
- aap
- bro 
- jojo
- koe
- kip
- haha
- hond
-     drop
Dictionary:
- aap
- hoi
- jojo
- koe
- kip
- haha
- hond
-     drop

Or you could use a Variable Length Array.

Keep in mind that according to the C Standard the function main without parameters shall be declared like

int main( void )
like image 79
Vlad from Moscow Avatar answered Nov 13 '22 02:11

Vlad from Moscow


Since "bro" is a string constant and dict[1] points to it, dict[1] points to a string constant.

When you use strcpy(dict[1]), ..., you are trying to modify the thing that dict[1] points to. But it points to a constant. So you are trying to modify a constant.

Constants cannot be modified.

like image 32
David Schwartz Avatar answered Nov 13 '22 00:11

David Schwartz