2009-04-19 18 views
0

多次元配列にポインタを格納する方法を知っていますか?私はそれがメインに私が午前の問題かもしれないと思う:ポインタの問題

// main.cpp 
#ifdef _DEBUG 
#define _CRTDBG_MAP_ALLOC 
#include <iostream> 
#include <fstream> 
#include <string> 
#endif 
#include "Word.h" 
using namespace std; 

const int WORD_SZ = 100; 
Word** g_wordArray; 
int g_arrSz; 

static char filePath[ FILE_PATH_SZ ] = {}; 
void FreeWordArray(); 

int main(const int argc, const char **argv) 
{ 
    int 
     wrdCount = 0; 
    char 
     usrMenuOption  = 0, 
     getFirstLetter = 0, 
     tmpArray[WORD_SZ] = {}, 
     *getWord = new char; 
    string 
     str, 
     str2; 
    ifstream 
     inFile, 
     inFile2; 
    do 
    { 
     cout << "Please make a selection: \n\ 
a) Read a text file\n\ 
b) Remove words starting with letter\n\ 
c) Print words to console\n\ 
d) Quit\n"; 
     cin >> usrMenuOption; 
     switch(usrMenuOption) 
     { 
     case'A': 
     case'a': 
      cout << "Enter a file name: "; 
      cin.sync(); 
      cin >> filePath; 
      inFile.open(filePath); 
      if (!inFile) return -1; 
      inFile >> tmpArray; // prime the eof flag. 
      while (!inFile.eof()) 
      { 
       inFile >> tmpArray; 
       wrdCount++; 
       g_wordArray = new Word *[wrdCount]; 

      } 
     inFile.close(); 
     inFile2.open(filePath); 
     while(!inFile2.eof() ) 
     { 
      inFile2 >> tmpArray; 
      // supplies the member functions with information from the file 
      g_wordArray[wrdCount] = new Word(tmpArray); 
      g_wordArray[wrdCount]->GetFirstLetterLower(); 
      g_wordArray[wrdCount]->GetWord(); 
     } 
     cout << wrdCount << " Words read from the file " << endl; 
     inFile2.close(); 
     break; 
     case'B': 
     case'b': 
     // information not found returning null 
       g_wordArray[wrdCount]->GetFirstLetterLower(); 
     break; 
     case'C': 
     case'c': 
       g_wordArray[wrdCount]->GetWord(); 
     break; 
     case'D': 
     case'd': 
     cout << "Quit Requested. " << endl; 
     break; 
     default: 
     cout << '"' << usrMenuOption << '"' << " Not Defined! " << endl; 
     } 

    } while (usrMenuOption != 'D' && usrMenuOption != 'd'); 


#ifdef _DEBUG 
    _CrtDumpMemoryLeaks(); 
#endif 
    cin.ignore(); 
    return 0; 
} 

void FreeWordArray() 
{ 
    delete[ ] g_wordArray; 
    return; 
} 


// Word.cpp 
#define _CRT_SECURE_NO_WARNINGS // disable warnings for strcpy 
#define ARRY_SZ 100 
#include <iostream> 
#include <fstream> 
#include "Word.h" 
#include <vector> 


using namespace std; 

// No paramaters. 
// Is this what im missing? 
// I just threw it in because of an error. 
Word::Word() 
{ 
} 

Word::Word(const char* word) 
{ 
    ptr_ = new char[ strlen(word) + 1 ]; 
    strcpy(ptr_, word ); 
    len_ = strlen(ptr_); 
} 

Word::~Word() 
{ 
    delete[ ] ptr_; 
    ptr_ = NULL; 
    len_ = NULL; 
} 

char Word::GetFirstLetterLower() 
{ 
    char myChar = tolower(ptr_[0]); 
    return myChar; 

} 

char* Word::GetWord() 
{ 
    Word *objectOne = new Word; 
    objectOne->ptr_ = ptr_; 
    strcpy(objectOne->ptr_, ptr_); 
    return objectOne->ptr_; 
} 

私の目標は、ファイル読み込みループに依存せずに私のg_wordArray[wrdCount]->SomeFunction()内のファイルから読み込まれたすべての単語を持つことです。

  • 実装ファイルでは、getFirstLetterLower下:新しい変数に毎回char *_ptrプライベートメンバを追加するために、私がやろうとしてきた何

    。 like someCharVar[0] = firstWord,someCharVar[1] = secondWord ...

  • ファイルの内容を単一のvaraibleに読み込みます。私が必要としているそれぞれの場合において、その曖昧さを回避すること。

私はそのアイデアを気に入っていますが、その方法を理解していません。助言がありますか?

+0

私はあなたの問題点を具体的に説明しようとお勧めします。あなたの質問 –

+0

...と何をしようとしていますか(コードではなく、解決しようとしている問題です。あなたが知っているすべてのための別の方法があるかもしれません! – dirkgently

答えて

-2

あなたの質問は何ですか?どこにエラーがありますか?

main()を短くして他の機能を使用すると考えましたか?このコードは読みにくいです。 さらに、do ... whileループは実際には使いにくいので、代わりにwhileループに切り替えることを検討してください。あなたは何らかのブール値を必要としますが、読みやすくするためには価値があります。

1

問題を再現できる最小限のコードを記入してください。今はかなり曇っています。このコードには多くの問題があると思われます。

 inFile >> tmpArray;  // prime the eof flag. 
     while (!inFile.eof()) 
     {  
       inFile >> tmpArray; 
       wrdCount++; 
       g_wordArray = new Word *[wrdCount]; 

     } 

ここではメモリがひどくリークしています。以前に割り当てられた 'g_wordArray'はどうなりますか?

また、 'n'個の要素を割り当てると、 'n番目'のインデックスにアクセスできません。メモリフットプリントは0〜(n-1)です。

g_wordArray[wrdCount] 

コードを再確認し、デバッグしてから最小限のコードを投稿してください。

1

IIUCでは、ファイルを読み込み、オプションで特定の文字で始まる単語を削除しようとしています。ここでも初歩的なあなたはそれを用いたSTLを達成することができる方法についてを、エラー処理およびいくつかのテンプレートなし、短い例です:

#include <iterator> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <fstream> 
#include <iostream> 

struct starts_with { 
    char mC; 
    starts_with(char c) : mC(c) {} 
    bool operator()(std::string const& s) { return s[ 0 ] == mC; } 
}; 

// uses commandline parameters for input arguments 
// usage: 
// ./test.exe "path/to/file" letter 
// 
// (assumes the file to be read is the first such parameter 
// the character to be checked for is the second parameter) 
int main(int argc, char *argv[ ]) { 
    using namespace std; 
    vector<string> v; 
    ifstream fStm(argv[ 1 ]); 
    istream_iterator<string> b(fStm), e; 

    remove_copy_if(b, e, back_inserter(v), starts_with(argv[ 2 ][ 0 ])); 

    copy(v.begin(), v.end(), ostream_iterator<string>(cout, "\n")); 

    return 0; 
} 
+1

'remove_copy_if'はどうですか?今週ちょうど私が(初めて)それを使用したと確信しています。それはあなたのcopy_ifと同じパラメータを持っています。 – quamrana

+0

ええ、確かに。ありがとう、私はちょうどこれを他の目的のために用意しました;-) – dirkgently

1

これは、ファイルを読み取るための一般的なアンチパターンです。
単語をtmpArrayに読み込みながらループ内でファイルの終わり(EOF)を検出すると、wrdCountは常に1になることに注意してください。結果のように、ここで

g_wordArray[wrdCount]->GetFirstLetterLower(); 

'wrdCountは' 'g_wordArray' 内の要素の数は次のとおりです。この代わりに

inFile >> tmpArray;  // prime the eof flag. 
while (!inFile.eof()) 
{  
    inFile >> tmpArray; 
    wrdCount++; 
    g_wordArray = new Word *[wrdCount]; 
} 

使用:あなたの配列に

/* 
* The result of the >> operator is a reference to a stream. 
* 
* When a stream is used in a boolean context (like a while loop) 
* it has a cast method that automatically returns an object 
* of a type that can be used as a boolean. 
* 
* The value of the boolean will be true if the file is still valid 
* and false if something went wrong (like reading past the end of file). 
* 
* So the loop will NOT be entered when you read past the EOF but will 
* be entered for every valid word that is read from the file. 
*/ 
while (inFile >> tmpArray) 
{  
    wrdCount++; 
    g_wordArray = new Word *[wrdCount]; 
} 
1

あなたのインデックスは常に間違っています'g_wordArray [wrdCount]'は、配列の最後を超えて要素1にアクセスしています。あなたはすべての場所でのメモリをリークしている>(wrdCount -1)

0

-

は、C/C++の配列は0からインデックスを作成し、これに有効な要素0を持っていることに注意してください。
このタイプのものを処理するには、STL標準コンテナを使用してください。

Word** g_wordArray; 

これはおそらく、より良いで表すことになります。そして、

std::vector<Word> g_wordArray; 

ではなく、このような配列のためのスペースを割り当てる:

g_wordArray = new Word *[wrdCount]; 
----- 
g_wordArray.reserve(wrdCount); 

そしてlastely新しい要素の変更を加えることは、このうそ

g_wordArray[wrdCount] = new Word(tmpArray); 
g_wordArray[wrdCount]->GetFirstLetterLower(); 
g_wordArray[wrdCount]->GetWord(); 

------ 

g_wordArray.push_back(Word(tmpArray)); 
g_wordArray[wrdCount].GetFirstLetterLower(); // Note we use . not -> 
g_wordArray[wrdCount].GetWord(); 

あなたのコードは、もはや厄介な新しい演算子を使用しなくなりました。したがって、あなたはメモリをリークすることはありません。