【问题标题】:How to pass two-dimensional string array into a function of another class如何将二维字符串数组传递给另一个类的函数
【发布时间】:2011-09-30 06:41:23
【问题描述】:

最近几天我遇到了一个困扰我的小难题。

我正在做一个项目,只是为了练习,其目的是提示用户输入一个单词并(在屏幕上)打印出相同的单词,但是用 ASCII 字符绘制的大字母。例如,如果用户输入单词“Hello”,输出将是:

H    H EEEEE L     L       OOO
H    H E     L     L      O   O
HHHHHH EEE   L     L     O     O
H    H E     L     L      O   O
H    H EEEEE LLLLL LLLLL   OOO

我在名为“UpperCaseFont”的命名空间内创建了一个名为“letters”的二维字符串数组。然后,我创建了一个名为 BigWord 的类,其目的是存储用户输入的单词,并提供几个有用的函数:printWord()、setWord()、getWord() 等。

与其将二维字符串数组存储在BigWord类中(这其实是我原本打算做的,但无法工作),后来我认为将字母数组传入会更好一个在 BigWord 中定义的函数 ( setAsciiFont() ),并且在 BigWord 类中有一个指向字母数组地址的指针。这样,不是每次创建新的 BigWord 对象时都创建一个新的字母数组,而是所有 BigWord 对象都可以引用相同的字母数组。节省内存和几个时钟周期(在这种规模的项目中并不重要,但我仍然想养成良好的编码习惯)。

但是,我似乎无法让它工作。我的代码如下:

主 .cpp 文件:

#include <iostream>
#include "Characters.h"

using namespace std;

int main(int argc, char** argv) {

   BigWord b;
   char temp[20];

   cin >> temp; // prompt user for word

   b.setWord(temp);
   cout << "Your word is: " << b.getWord() << endl;

   //Set the ASCII font for the BigWord object to use 
   b.setAsciiFont(UpperCaseFont::letters);

   b.printWord();

   return 0;
}

头文件(Characters.h):

#ifndef CHARACTERS
#define CHARACTERS

#include <iostream>

using namespace std;

namespace UpperCaseFont {
    // constant; font should not be changeable
    // all characters will have 5 rows.
    const string letters[][5] = {
        {
            "    A    ",
            "   A A   ",
            "  AAAAA  ",
            " A     A ",
            "A       A"
        },
        {
            "  BBBB   ",
            "  B   B  ",
            "  BBB    ",
            "  B   B  ",
            "  BBBB   "
        },
        {
            "   CCCC  ",
            "  C      ",
            " C       ",
            "  C      ",
            "   CCCC  "
        }
    }; // not finished making all letters yet.
}

class BigWord {
private:
    int wordLength;
    char word[];

    // letters[][5] will point to the location of UpperCaseFont::letters array.
    const string* letters[][5];

    void toUpperCase(char* str);
public:

    void setWord(char w[]);

    string getWord() {
        return word;
    }

    void setAsciiFont(const string [][5]); // PROBLEM WITH THIS FUNCTION

    void printWord(void);

};

void BigWord::setWord(char* w) {
    wordLength = strlen(w);
    //    cout << "Word Length: " << wordLength << endl;
    std::copy(w, w + wordLength, word);
    BigWord::toUpperCase(word);
}

void BigWord::toUpperCase(char* str) {
    // convert a string to Upper case letters for printWord algorithm to work
    for (int i = 0; i < wordLength; i++) {
        if (str[i] > 'Z') {
            str[i] -= ('a' - 'A');
        }
    }
}

void BigWord::setAsciiFont(const string font[][5]) { // ***PROBLEM***
    letters = &font; // How can I get this to work??
}

void BigWord::printWord() {
    // print top line of all ASCII Font letters, move to next line, repeat etc.
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < wordLength; j++) {
            // subtracts 65 (ASCII 'A') to arrive at index 0 if character == A.
            cout << *letters[word[j] - 'A'][i];
        }
        cout << endl;
    }
}


#endif

当我尝试编译此代码时,我收到以下错误:

Characters.h:81: 错误:const std::string (**)[5]' toconst std::string*[0u][5]' 的赋值类型不兼容

我对 C++ 很陌生(几周前开始,但我有一些 Java 经验来支持我),甚至对指针也很陌生,所以我不完全知道我做错了什么......任何谷歌搜索都无济于事。 我知道使用数组的名称将充当指向该数组的第一个索引的指针,但是它如何与二维(或多维)数组一起使用? 如果需要,我可以编写一个函数,将 UpperCaseFont::letters 数组转换为一维数组,如果二维数组太难处理的话。

基本上,要深入了解我真正要问的问题: 如何将指针分配给已传递给位于头文件中的类中的函数的二维字符串数组?

【问题讨论】:

    标签: c++ arrays pointers compiler-errors


    【解决方案1】:

    问题在于 C++ 不支持将数组作为参数传递。 当你写:

    void setAsciiFont( std::string const font[][ 5] );
    

    编译器将其转换为:

    void setAsciiFont( std::string const (*font)[5] );
    

    当你传递一个数组时,会发生类似的转换。

    最简单的解决方案就是在 类来反映这一点:

    std::string const (*letters)[5];
    

    由于 C++ 中定义索引的方式,这将完全有效 就好像您拥有完整的数组作为成员一样,即letters['n'][line] 会选择正确的字符串。

    顺便说一句:我会将字体作为参数传递给 BigWord。这样,您就不会意外地尝试输出 无需设置。

    【讨论】:

    • 谢谢!我终于让它工作了=)。哦,我接受了你的建议,将字体参数放入 BigWord 的构造函数中,这样做很有意义……代码越不容易出错,越好 =P。
    【解决方案2】:

    数组可以通过引用传递。所以下面的函数,

    void setAsciiFont(const string [][5]); // PROBLEM WITH THIS FUNCTION
    

    应该是(同时声明两个维度​​),

    void setAsciiFont(const string (&letters)[3][5]); // ok
                                  ^^^^ pass by reference
    

    如果你总是不确定维度,你可以模板化这个函数:

    template<size_t ROW, size_t COL>
    void setAsciiFont(const string (&letters)[ROW][COL]); // ok
    

    【讨论】:

    • 引用解决方案实际上相当不错:但是,要有效地使用它,您必须将类中的数据声明更改为引用,并将letters 传递给构造函数(无论如何,恕我直言更可取)。并删除模板建议:如果您不知道维度,则无论如何都不能安全地使用该数组。
    【解决方案3】:

    您只需要正确地键入字母成员变量。你想给它分配一个const string (*)[5](这是const string [][5]衰减到的),所以它应该有这种类型

    // letters[][5] will point to the location of UpperCaseFont::letters array.
    const string (*letters)[5];
    

    否则,它应该可以工作。

    【讨论】:

      猜你喜欢
      • 2015-05-27
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 2013-02-27
      • 1970-01-01
      • 2020-02-19
      相关资源
      最近更新 更多