无法使用C中的strcpy从指针数组复制字符串?

无法使用C中的strcpy从指针数组复制字符串?,c,undefined-behavior,strcpy,string-literals,C,Undefined Behavior,Strcpy,String Literals,我正在做一个练习,其中字符指针数组作为存储单词的一种方式。我不明白为什么不能使用strcpy将单词“hoi”复制到main函数中数组的第二个元素。当我编译代码时,我在代码块中得到消息“程序已停止工作” 函数“numberOfWordsInDict”和“printDict”工作正常 提前谢谢 int numberOfWordsInDict(char **dict) { int i, cnt = 0; for(i = 0; i < 10; i++) {

我正在做一个练习,其中字符指针数组作为存储单词的一种方式。我不明白为什么不能使用strcpy将单词“hoi”复制到main函数中数组的第二个元素。当我编译代码时,我在代码块中得到消息“程序已停止工作”

函数“numberOfWordsInDict”和“printDict”工作正常

提前谢谢

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;
}
int numberOfWordsInDict(字符**dict)
{
int i,cnt=0;
对于(i=0;i<10;i++)
{
if(dict[i]!=NULL)
{
cnt++;
}
}
返回cnt;
}
作废打印目录(字符**目录)
{
int i=0;
printf(“字典:\n”);
if(numberOfWordsInDict(dict)==0)
{
printf(“字典是空的。\n”);
}否则
{
对于(i=0;i<10;i++)
{
printf(“-%s\n”,dict[i]);
}
}
}
int main()
{
字符*dict[10]={
“aap”、“bro”、“jojo”、“koe”、“kip”,
“哈哈”,“洪都拉斯”,“滴落”,空,空};
char*newWord1=“hoi”;
printDict(dict);
strcpy(dict[1],newWord1);
printDict(dict);
返回0;
}

指针指向的内存是只读的,因为
“string”
是一个字符串文本。

据我所知,不可能写入字符串文本。

因为
“bro”
是一个字符串常量,
dict[1]
指向它,
dict[1]
指向一个字符串常量


当您使用strcpy(dict[1]),…
时,您试图修改dict[1]
指向的内容。但它指向一个常数。所以您正在尝试修改一个常量


无法修改常量。

数组
dict
是指向字符串文本的指针数组

在这份声明中

strcpy(dict[1],newWord1);
您正在尝试将一个字符串文字复制到另一个字符串文字中

<>字符串文字在C和C++中是不可修改的。任何修改strig文本的尝试都会导致程序的未定义行为

来自C标准(6.4.5字符串文字)

7未说明这些数组是否不同,前提是它们的 元素具有适当的值如果程序试图 修改这样一个数组,行为是未定义的。

如果要复制其元素中的字符串文字或动态分配的字符数组的一维数组,则应声明二维字符数组

程序可以按以下方式运行

#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;
}
或者可以使用可变长度数组

请记住,根据C标准,不带参数的函数
main
应声明如下

int main( void )

您需要在RW内存中保留存储空间,并在那里复制文本。您不必手动执行此操作:)


dict[1]
指向字符串文字的第一个字符。修改strcpy(dict[1],newWord1)所做的字符串文本会产生未定义的行为。非常感谢大家!这是一个非常常见的常见问题。如果您查看下面的“字符串”,则有几个规范帖子可用于进一步阅读/close-as-duplicate。写入字符串文字并非“不可能”。尝试这样做是未定义的行为-它可能“起作用”,也可能不起作用。@chux感谢您的评论;这就是我的实际意思。细节:C没有指定“字符串文字是不可修改的”。试图这样做是不可能的。很好,你强调了这一点。@Vlad来自莫斯科,你的代码是UB<代码>字符目录[10][9]={“aap”、“bro”、“jojo”、“koe”、“kip”、“haha”、“hond”、“drop”}然后迭代
size\t numberOfWordsInDict(char-dict[][N]){size\t N=0;而(*dict[N])++N;return N;}
幸运的是,在表的最后一个元素后面有某种零值。@PeterJ你错了。我不走运。我只是一个合格的失业者。:)数组被声明为有10个元素。但仅明确提供了8个初始值设定项。。其余两个元素用零初始化。也就是说,它们包含空字符串。代码格式正确。@PeterJ最初的问题是,数组有两个元素的sentinel值为NULL。因此,考虑到函数是为具有sentinel值的数组编写的,那么用作参数的数组应具有sentinel值。在我的程序中,数组也有一个哨兵值。它的sentinel值是空字符串,而不是NULL。所以我不明白你说的是什么“正常语言”。至于我,我现在谈论的是C,使用问题中所示的方法。@Vlad来自莫斯科,那么你的函数是如何处理的:
char dict[10][9]={“aap”、“bro”、“jojojo”、“koe”、“kip”、“haha”、“hond”、“drop”、“mod”、“bod”}是否为UB?C有各种常量,但未指定字符串常量。字符串文字不是真正的常量,但尝试更改它们就像
strcpy(dict[1]),…
int main( void )
#define MAXDICTSIZE 25

int numberOfWordsInDict(char dict[][MAXDICTSIZE], int dictsize)
{
    int i, cnt = 0;
    for (i = 0; i < dictsize; i++)
    {
        if (strlen(dict[i]))
        {
            cnt++;
        }
    }
    return cnt;
}

void printDict(char dict[][MAXDICTSIZE], int dictsize)
{
    int i = 0;
    printf("Dictionary:\n");
    if (numberOfWordsInDict(dict, dictsize) == 0)
    {
        printf("The dictionary is empty.\n");
    }
    else
    {
        for (i = 0; i < dictsize; i++)
        {
            if(strlen(dict[i]))printf("- %s\n", dict[i]);
        }
    }
}
char dict[10][MAXDICTSIZE] = {
    "aap", "bro ", "jojo", "koe", "kip",
    "haha", "hond", "    drop", "","" };

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