2017-08-10 78 views
4

我正在做一個練習,其中一個字符指針數組作爲存儲單詞的一種方式。我不明白爲什麼我不能使用'strcpy'將單詞'hoi'複製到主函數中數組的第二個元素。當我編譯代碼時,我在CodeBlocks中收到'程序已停止工作'的消息。不能從C中的strcpy指針數組中複製字符串?

函數'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; 
} 
+1

'快譯通[1]'指向一個字符串的第一個字符。修改'strcpy(dict [1],newWord1)'這樣的字符串文字會導致未定義的行爲。 – Peter

+0

非常感謝大家! –

+0

這是一個令人難以置信的常見問題。如果您在「字符串」下面查看[Stack Overflow C FAQ](https://stackoverflow.com/tags/c/info),有幾個規範的帖子可用於進一步閱讀/重複關閉。 – Lundin

回答

0

存儲器中的指針指向是隻讀作爲"string"是文字的字符串。

0

據我的理解,寫入字符串文字是不可能的。

+2

寫入_string literal_不是不可能的。試圖這樣做是_undefined行爲_ - 它_might_「工作」,它可能不會。 – chux

+0

@chux感謝您的評論;這就是我的意思。 – Codor

1

由於"bro"是一個字符串常量,並且dict[1]指向它,dict[1]指向一個字符串常量。

當您使用strcpy(dict[1]), ...時,您試圖修改dict[1]指向的東西。但它指向一個常數。所以你試圖修改一個常量。

常量不能修改。

+0

C有各種_constants_,但沒有指定_string常量_。 _string literals_不是真正的常量,但試圖改變他們是UB像'的strcpy(字典[1]),...' – chux

2

數組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; 
} 

程序輸出是

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

或者你可以使用一個可變長度數組。

請記住,根據C標準的功能main不帶參數應聲明如下

int main(void) 
+0

詳細內容:C不指定「字符串文字是不可修改的。」 UB試圖這樣做。很好,你已經強調了這個UB。 – chux

+0

@Vlad來自莫斯科,你的代碼是UB。 '炭字典[10] [9] = { 「AAP」, 「兄弟」, 「喬喬」, 「千奧斯特」, 「千磅」, 「哈哈」, 「杭德」, 「降」 };'然後你迭代'的size_t numberOfWordsInDict(字符字典[] [N]) { 爲size_t N = 0; while(* dict [n])++ n; return n; 「你很幸運,你在表格的最後一個元素之後有某種零值。 –

+0

@PeterJ你錯了。我不幸運。我只是一個合格的失業者。:)這個數組被聲明爲有10個元素。但只明確提供了8個初始化器。其餘兩個元素用零初始化。那是他們包含空字符串。代碼格式正確。 –

0

您需要在RW存儲和複製的文字有保留的存儲空間。你不必做手工:)

#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]));