2012-11-01 24 views
5

Utknąłem w zadaniach domowych. Muszę odczytać tekst z pliku, przydzielić każde słowo do pamięci, a następnie wskazać użytkownikowi wskaźnik, aby wysłać go do vector<string*>. Mój program nadpisuje wektor nowym słowem z pliku zamiast go tylko dodawać. Nie rozumiem, dlaczego tak się dzieje.Wektor w C++ ze wskaźnikiem

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <string> 
using namespace std; 


void WordFunctions(string *pstr, vector<string*> &words) 
{ 
    words.push_back(pstr); 
} 
int main(){ 
    ifstream file; 
    vector<string*> a; 
    string word; 
    int w =0; 
    file.open("word.txt"); 
    while (!file.eof()) 
    { 
     w++; 
     file >> word; 

     WordFunctions(&word, a); 
    } 
    file.close(); 

    for (int i=0;i<10;i++){ 
     cout<<(*a[i])<<" "; 
     delete a[i]; 
    } 

    system ("pause"); 
} 
+1

Rany .. Twoje zadanie faktycznie zmusza cię do użycia wektora wskaźników i nie wyjaśnia, dlaczego jest to okropny pomysł? Tak, jak wiesz, masz teraz obowiązek ręcznego zwolnienia każdego elementu w twoim wektorze, negując ogromną korzyść, którą daje ci wektor. * czasami * musisz przechowywać wskaźniki w wektorze (nie często!) iw takim przypadku użyjesz inteligentnego wskaźnika, tj. 'unique_ptr' lub czegoś podobnego. Pamiętaj, aby powiedzieć o tym swojemu nauczycielowi, gdy następnym razem go zobaczysz. –

Odpowiedz

3

Albo użyć vector<string> lub przydzielić nowy ciąg na stercie:

void WordFunctions(string *pstr, vector<string*> &words) 
{ 
    words.push_back(new string(*pstr)); 
} 
+0

Z pewnością lepiej jest przekazać wartość przez const ref, a nie wskaźnik? potem nie ma nieprzyjemnych dereferencji itp. ... – Caribou

+0

@Caribou Tak, jest. Ale chciałem iść z minimalnymi zmianami. W przeciwnym razie musisz także zmienić stronę wywołującą. –

+0

prawda - właśnie się tu kręciło;) – Caribou

1

Ty pchają ten sam element do wektora, który jest adres słowa. I masować trochę na kodzie

// pass reference to eliminate copy 
void WordFunctions(string &str, vector<string> &words) 
{ 
    words.push_back(str); 
} 
int main(){ 
    ifstream file; 
    vector<string> a; // you want to store string not the address of the string 
    string word; 
    int w =0; 
    file.open("words.txt"); 
    while (!file.eof()) 
    { 
     w++; 
     word.clear(); // clear the content before store something into it 
     file >> word; 
     WordFunctions(word, a); 
    } 
    file.close(); 

    for (size_t i=0;i<a.size();i++){ // use size instead of hard code magic number 
     cout<<(a.at(i))<<" "; // use at function instead of [] 
    } 

    system ("pause"); 
} 
-1

ciąg word ma zawsze ten sam adres w pamięci, więc w pętli zmieniasz wartość ciągu, ale potem zadzwonić WordFunctions przechodząc do niego zawsze ten sam adres .

Jeśli jest to ograniczenie korzystania vector<string*> zamiast vector<string>, będzie prawdopodobnie trzeba przydzielić pamięci dla nowych ciągów w pętli, skopiuj tam swoje słowo, a następnie zdać nowy odnośnik do WordFunctions

char *wordPtr 

while (!file.eof()) 
{ 
    w++; 
    file >> word; 

    wordPtr = (char *)malloc((strlen(word)+1)*sizeof(char)); 
    strcpy(wordPtr, *word); 

    WordFunctions(wordPtr, a); 
} 
+1

Nie jestem całkowicie pewien, że to działa, ale pomysł powinien być taki. – unziberla

+1

Hej, ten facet próbuje użyć C++. Dlaczego proponujesz użycie 'malloc'? – Ruu

+1

Masz rację! To było tak podobne do klasycznych prac domowych, które zrobiłem w C, że rozwiązałem to w ten sposób! Zobaczyłem teraz poprawne rozwiązanie i wznowiono – unziberla

Powiązane problemy