2011-09-30 79 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]; 

否則,它應該工作。

相關問題