如何将二维字符串数组传递给另一个类的函数

发布于 2024-12-07 14:49:54 字数 3753 浏览 0 评论 0原文

我遇到了一个小难题,这几天一直困扰着我。

我正在开发一个项目,只是为了练习,其目标是提示用户输入一个单词并打印(到屏幕上)同一个单词,但以 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]' 到const std::string*[0u][5]'

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

本质上,要弄清楚我真正要问的是什么: 如何将指针分配给已传递到头文件中类内的函数的二维字符串数组?

I have come across a little dilemma that has stumped me for the last few days.

I am working on a project, just for practice, where the objective is to prompt the user to input a word and print out (to the screen) that same word, but in large letters drawn in ASCII characters. For example, if the user typed in the word "Hello", the output would be:

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

I created a two dimensional string array called 'letters' inside a namespace called "UpperCaseFont". Then, I created a class called BigWord, whose purpose would be to store a user-input word, and provide several useful functions: printWord(), setWord(), getWord() etc.

Rather than storing the two-dimensional string array inside the BigWord class (which is actually what I originally intended to do, but couldn't get working), I later thought that it would be better to pass in the letters array into a function ( setAsciiFont() ) defined in BigWord and have a pointer in the BigWord class point to the address of the letters array. This way, instead of creating a new letters array each time a new BigWord object was created, all BigWord objects could just reference the same letters array. Saving memory and a few clock cycles too (not that it matters in a project of this size, but I still want to develop good coding habits).

However, I cannot seem to get it working. My code is below:

The main .cpp file:

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

The header file (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

When I attempt to compile this code, I get the following error:

Characters.h:81: error: incompatible types in assignment of const
std::string (**)[5]' to
const std::string*[0u][5]'

I'm fairly new to C++ (started a couple weeks ago, but I have some Java experience to back me up), and even newer to pointers, so I don't exactly know what I am doing wrong...and any googling has been to no avail.
I understand that using the name of an array will act as the pointer to the first index of that array, but how does it work with two-dimensional (or multi-dimensional) arrays?
If needed, I can write a function to convert the UpperCaseFont::letters array into a one-dimensional array if it turns out two dimensional arrays are too troublesome to deal with.

Essentially, to get down to what I'm really asking:
How can I assign a pointer to a two-dimensional string array that has been passed into a function within a class located in a header file?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时光磨忆 2024-12-14 14:49:55

问题是 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。这样,您就不会意外地尝试输出
没有设置它。

The problem is that C++ doesn't support passing arrays as arguments.
When you write:

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

the compiler converts this to:

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

When you pass an array, a similar conversion occurs.

The simplest solution is just to change your variable declaration in the
class to reflect this:

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

Because of the way indexation is defined in C++, this will work exactly
as if you had the complete array as a member, i.e. letters['n'][line]
will pick up the right string.

And BTW: I'd pass the font as a parameter to the constructor of
BigWord. That way, there's no way you can accidentally try to output
without having set it.

秋意浓 2024-12-14 14:49:55

数组可以通过引用传递。因此,以下函数

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

Arrays can be passed by reference. So following function,

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

should be (with declaring both the dimensions),

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

You can templatize this function, if you are not sure of the dimension always:

template<size_t ROW, size_t COL>
void setAsciiFont(const string (&letters)[ROW][COL]); // ok
尽揽少女心 2024-12-14 14:49:55

您只需要正确键入字母成员变量即可。您想要为其分配一个 const string (*)[5] (这是 const string [][5] 衰减的结果),所以它应该具有这种类型

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

否则,它应该有效。

You just need to properly type the letters member variable. You want to assign a const string (*)[5] (which is what const string [][5] decays to) to it, so it should have this type

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

Otherwise, it should work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文