简体   繁体   English

迭代const char *数组

[英]Iterating through const char* array

I have an really simple example of array of const char's and one function supposed to print them out (iterate through the chosen one). 我有一个非常简单的const char数组的例子和一个应该打印出来的函数(遍历所选的一个)。 Contrary all my expectations, it's iterating through all of them and not only the one that was passed as argument. 与我的所有期望相反,它正在迭代所有这些,而不仅仅是作为参数传递的那个。

#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;
}

The result i would expect is that the function printFruit with oranges given as argument will print ORANGE and RED ORANGE, meanwhile i get printed ALL of the fruits defined (from other arrays), like this: 我期望的结果是作为参数给出橙色函数printFruit将打印ORANGE和RED ORANGE,同时我打印所有定义的水果(来自其他数组),如下所示:

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

Sorry for my ignorance but why is this happening ? 对不起我的无知,但为什么会这样?

Edit: I followed this question: defining and iterating through array of strings in c that is similar to mine. 编辑:我遵循了这个问题: 定义和迭代c中与我类似的字符串数组

You are having UB here. 你在这里有UB。 Your condition 你的病情

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

will never be met because there are no elements that are equal to \\0 . 永远不会满足,因为没有等于\\0元素。

All the arrays are placed exactly one after another in the memory. 所有数组都在内存中一个接一个地放置。 Your i keeps increasing forever. 你的i永远在增加。 On i = 1 you are on the first string in oranges . i = 1你在oranges的第一个字符串。 On i = 2 you are on the second element. i = 2你在第二个元素上。

After that, i becomes 3. Since right after oranges , in your mamory lies the apples array, your pointer starts pointing to it and the app prints APPLE . 在那之后, i变成了3.因为在oranges之后,在你的妈妈的谎言apples阵列,你的指针开始指向它,应用程序打印APPLE On i = 4 the pointer is on the lemons array and the app prints LEMONS . i = 4 ,指针位于lemons数组上,应用程序打印LEMONS After that you effectively go out of your own memory which for me results in a crash. 之后,你有效地走出了自己的记忆,这对我来说会导致崩溃。

To fix that you need to explicitly add an empty element into each of the arrays, eg 要解决此问题,您需要在每个数组中显式添加一个空元素,例如

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

You are checking that fruit[i] != '\\0' . 你正在检查fruit[i] != '\\0' That is wrong because fruit[i] is a char * , not a char. 这是错误的,因为fruit[i]char * ,而不是char。 Furthermore, your vectors aren't terminated. 此外,您的向量不会终止。 You probably wanted to check whether fruit[i] != 0 , or *fruit[i] != '\\0' . 您可能想检查fruit[i] != 0 ,或*fruit[i] != '\\0' In the first case, you need to terminate the vectors like this: 在第一种情况下,您需要终止这样的向量:

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

In the second: 在第二:

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

IMHO, you'd be better off knowing exactly how many elements that you're dealing with. 恕我直言,你最好知道你正在处理多少元素。 The bad news is that a simple array of character pointers won't tell you (it's not a std::vector ) so you won't be able to discover it in your printFruit function. 坏消息是一个简单的字符指针数组不会告诉你(它不是std::vector )所以你将无法在printFruit函数中发现它。

The good news, however, is that it is available at compile time so you don't have to worry about the overhead of finding it out. 然而,好消息是它可以在编译时使用,因此您不必担心找到它的开销。 The following shows what I mean: 以下显示了我的意思:

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

Since you're using C++ though, I'd strongly recommend that you use one of the standard collection types such as vector as they're much safer when it comes to bounds checking, memory allocation etc. 既然您正在使用C ++,我强烈建议您使用其中一种标准集合类型,例如vector因为它们在边界检查,内存分配等方面更安全。

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

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

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

in memory will looks somthing like 在记忆中会看起来像

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

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

will end when you reach the end of "big array" which is "LEMON" 当你到达“LEMON”的“大阵列”结束时将结束

to make your code working you need memory to looks like "ORANGE""RED ORANGE"0"APPLE"0"LEMON"0 so 为了使你的代码工作你需要内存看起来像“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"
};

Your arrays are located in memory one after another so it continues printing others because the while condition is false 您的阵列一个接一个地位于内存中,因此它会继续打印其他数据,因为while条件为false

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM