簡體   English   中英

迭代const char *數組

[英]Iterating through const char* array

我有一個非常簡單的const char數組的例子和一個應該打印出來的函數(遍歷所選的一個)。 與我的所有期望相反,它正在迭代所有這些,而不僅僅是作為參數傳遞的那個。

#include <iostream>

const char* oranges[] = {
    "ORANGE",
    "RED ORANGE"
};

const char* apples[] = {
    "APPLE"
};

const char* lemons[] = {
    "LEMON"
};

void printFruit(const char** fruit){
    int i =0;
    while (fruit[i] != '\0'){
        std::cout << "---------------------\n";
        std::cout << fruit[i] << "\n";
        i++;
    }
}

int main (int argc, const char * argv[])
{
   printFruit(oranges); 
   return 0;
}

我期望的結果是作為參數給出橙色函數printFruit將打印ORANGE和RED ORANGE,同時我打印所有定義的水果(來自其他數組),如下所示:

---------------------
ORANGE
---------------------
RED ORANGE
---------------------
APPLE
---------------------
LEMON

對不起我的無知,但為什么會這樣?

編輯:我遵循了這個問題: 定義和迭代c中與我類似的字符串數組

你在這里有UB。 你的病情

while (fruit[i] != '\0')

永遠不會滿足,因為沒有等於\\0元素。

所有數組都在內存中一個接一個地放置。 你的i永遠在增加。 i = 1你在oranges的第一個字符串。 i = 2你在第二個元素上。

在那之后, i變成了3.因為在oranges之后,在你的媽媽的謊言apples陣列,你的指針開始指向它,應用程序打印APPLE i = 4 ,指針位於lemons數組上,應用程序打印LEMONS 之后,你有效地走出了自己的記憶,這對我來說會導致崩潰。

要解決此問題,您需要在每個數組中顯式添加一個空元素,例如

const char* oranges[] = {
    "ORANGE",
    "RED ORANGE",
    0
};

你正在檢查fruit[i] != '\\0' 這是錯誤的,因為fruit[i]char * ,而不是char。 此外,您的向量不會終止。 您可能想檢查fruit[i] != 0 ,或*fruit[i] != '\\0' 在第一種情況下,您需要終止這樣的向量:

const char* oranges[] = {
    "ORANGE",
    "RED ORANGE",
    0  // or NULL
};

在第二:

const char* oranges[] = {
    "ORANGE",
    "RED ORANGE",
    ""
};

恕我直言,你最好知道你正在處理多少元素。 壞消息是一個簡單的字符指針數組不會告訴你(它不是std::vector )所以你將無法在printFruit函數中發現它。

然而,好消息是它可以在編譯時使用,因此您不必擔心找到它的開銷。 以下顯示了我的意思:

void printFruit(const char** fruit, int fruitSize){
    int i =0;
    while (i < fruitSize){
        std::cout << "---------------------\n";
        std::cout << fruit[i] << "\n";
        i++;
    }
}

int main (int argc, const char * argv[])
{
   // The second parameter can be worked out by the compiler.
   printFruit(oranges, sizeof(oranges)/sizeof(const char*) ); 
   return 0;
}

既然您正在使用C ++,我強烈建議您使用其中一種標准集合類型,例如vector因為它們在邊界檢查,內存分配等方面更安全。

const char* oranges[] = {
    "ORANGE",
    "RED ORANGE"
};

const char* apples[] = {
    "APPLE"
};

const char* lemons[] = {
    "LEMON"
};

在記憶中會看起來像

“ORANGE”“RED ORANGE”“APPLE”“LEMON”

while (fruit[i] != '\0'){
    std::cout << "---------------------\n";
    std::cout << fruit[i] << "\n";
    i++;
}

當你到達“LEMON”的“大陣列”結束時將結束

為了使你的代碼工作你需要內存看起來像“ORANGE”“RED ORANGE”0“APPLE”0“LEMON”0所以

   const char* oranges[] = {
        "ORANGE",
        "RED ORANGE",
    0
    };

    const char* apples[] = {
        "APPLE",
    0
    };

    const char* lemons[] = {
        "LEMON"
     ,0
    };
const char* oranges[] = {
    "ORANGE",
    "RED ORANGE",
    "\0"
};

您的陣列一個接一個地位於內存中,因此它會繼續打印其他數據,因為while條件為false

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM