2011-09-30 66 views
1

我所遇到已经难倒我的最后几天有点左右为难的功能。如何通过二维字符串数组到另一个类

我工作的一个项目,只是为了实践,这里的目的是提示用户输入一个单词,打印出来(屏幕)是同一个词,但在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”命名空间内的二维字符串数组被称为“字母”。然后,我创建了一个名为BigWord的类,其目的是存储用户输入的单词,并提供几个有用的函数:printWord(),setWord(),getWord()等。

而不是存储双字节字符串,在长单词类中维字符串数组(事实上,我原本打算做的是,但却无法工作),我后来想,这将是最好的字母数组中通入中定义的函数(setAsciiFont()) BigWord并在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: error: incompatible types in assignment of const std::string (**)[5]' to const std::string*[0u][5]'

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

本质上,要回到我真正要问的问题: 如何分配一个指向已传递到位于头文件中的类中的函数的二维字符串数组的指针?

回答

2

问题是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。这样,您不可能无意中尝试输出 而未设置它。

+0

谢谢!我终于搞定了=)。 哦,我听取了你的建议,把字体参数放到BigWord的构造函数中,这样做很有意义......代码的错误越少,= P越好。 – Inventor22

0

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

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 
+0

参考解决方案实际上相当不错:但要有效地使用它,必须将类中的数据声明更改为引用,并将'letters'传递给构造函数(恕我直言,最好)。并放弃模板建议:如果您不知道维度,则无论如何您都无法安全地使用该数组。 –

0

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

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

否则,它应该工作。

相关问题