使用 for 循环打印字符串数组无法正常运行 (C++)

Printing string array with for-loop doesn't function properly (C++)

我是 C++ 的新手,只是想尝试一些东西,在本例中特别是数组。我想将字符串数组打印到控制台,但它要么以二进制形式打印随机内容,要么告诉我出现了分段错误,要么什么都不做。

最初的程序有点复杂,但我试图尽可能减少额外的东西,以便我能看到问题所在,但没有成功。

#include <iostream>
#include <string>

using namespace std;

int main() {

    string stArr[] = {" 1 | ","_"," | ","_"," | ","_"," | "};
    for(int i = 0; i < sizeof(stArr); i++) {
           cout << stArr[i];
    }

    return 0;
}

现在,预期的输出显然是数组。但我通常得到的是这样的:UH��AWAVAUATSH��(L��%��!I����#E��K��H��v!H��H��%H��=��!。 {��!I��H����I������H��=_!��Q��!����t��H��D��A����D����;u��u��u ����H�e�E1��H� [等]

提前致谢!

检查,sizeof(strArray)的值是多少。我打赌你假设它是 7(即数组中的字符串数)。

剧透:好吧,肯定不是。 sizeof(strArray) returns整个数组占用的内存量,即7个字符串。它是一个大于 7 的数字,因此在迭代期间您读取数组边界之外的内存。

将它除以一个元素的大小(例如 sizeof(strArray)/sizeof(string))以获得您期望的大小。

for循环中的这个条件

i < sizeof(stArr)

没有意义。它不提供数组中元素的数量。

至少你得写

i < sizeof(stArr) / sizeof( *stArr )

例如,如果您有一个包含 NT 类型元素的数组,则使用此公式

计算数组的大小
sizeof( array ) = N * sizeof( T )

因此,要在知道数组大小的情况下获取数组中元素的数量以及可以编写的元素大小

N = sizeof( array ) / sizeof( T )

但是使用 range-based for 循环要简单得多。

for ( const auto &s : stArr ) std::cout << s;

如果您的编译器支持 C++ 17,那么您可以使用 header <iterator> 中声明的标准泛型函数 std::size。例如

#include <iostream>
#include <string>
#include <iterator>

using namespace std;

int main() {

    string stArr[] = {" 1 | ","_"," | ","_"," | ","_"," | "};
    for ( size_t i = 0; i < size( stArr ); i++) {
           cout << stArr[i];
    }
}

否则你可以使用header<type_traits>中定义的结构std::extent如下方式

#include <iostream>
#include <string>
#include <type_traits>

using namespace std;

int main() {

    string stArr[] = {" 1 | ","_"," | ","_"," | ","_"," | "};
    for ( size_t i = 0; i < extent<decltype( stArr )>::value; i++) {
           cout << stArr[i];
    }
}

sizeof(stArr) 为您提供整个数组的 总字节大小 。它不会为您提供 元素计数 ,这正是您要查找的内容。因此,您的循环超出了数组的边界,这就是您在输出中出现垃圾的原因。

要得到数组的元素个数,需要用数组的字节大小除以数组中单个元素的大小,eg:

#include <iostream>
#include <string>

int main() {

    std::string stArr[] = {" 1 | ","_"," | ","_"," | ","_"," | "};
    int count = sizeof(stArr) / sizeof(stArr[0]);

    for(int i = 0; i < count; ++i) {
        std::cout << stArr[i];
    }

    return 0;
}

也就是说,如果您使用的是 C++17 或更高版本的编译器,则可以使用 std::size() 获取静态数组的元素数:

#include <iostream>
#include <string>
#include <iterator>

int main() {

    std::string stArr[] = {" 1 | ","_"," | ","_"," | ","_"," | "};
    size_t count = std::size(stArr);

    for(int i = 0; i < count; ++i) {
        std::cout << stArr[i];
    }

    return 0;
}

或者,如果您使用的是 C++11 编译器,则可以改用 std::extent

#include <iostream>
#include <string>
#include <type_traits>

int main() {

    std::string stArr[] = {" 1 | ","_"," | ","_"," | ","_"," | "};
    size_t count = std::extent<decltype(stArr)>::value;

    for(int i = 0; i < count; ++i) {
        std::cout << stArr[i];
    }

    return 0;
}

也就是说,如果您使用的是 C++11 或更高版本的编译器,请考虑改用 std::array

#include <iostream>
#include <string>
#include <array>

int main() {

    std::array<std::string, 7> stArr = {" 1 | ", "_", " | ", "_", " | ", "_", " | "};
    // or: in C++17 and later:
    // std::array stArr{" 1 | ", "_", " | ", "_", " | ", "_", " | "};

    std::size_t count = stArr.size();

    for(size_t i = 0; i < count; ++i) {
        std::cout << stArr[i];
    }

    return 0;
}

或者,您也可以使用 ranged-based for loop:

#include <iostream>
#include <string>

int main() {

    std::string stArr[] = {" 1 | ", "_", " | ", "_", " | ", "_", " | "};
    // or std::array...

    for(auto &s : stArr) {
        std::cout << stArr[i];
    }

    return 0;
}

否则,如果您不使用 C++11 或更高版本的编译器,请考虑使用 std::vector

#include <iostream>
#include <string>
#include <vector>

int main() {

    std::vector<std::string> stArr;
    stArr.push_back(" 1 | ");
    stArr.push_back("_");
    stArr.push_back(" | ");
    stArr.push_back("_");
    stArr.push_back(" | ");
    stArr.push_back("_");
    stArr.push_back(" | ");

    std::size_t count = stArr.size();

    for(size_t i = 0; i < count; ++i) {
        std::cout << stArr[i];
    }

    return 0;
}