2009-08-01 15 views
10

Jestem początkującym w C++. Próbuję mieć wskaźnik char jako parametr wyjściowy dla funkcji. Ale zmiany wprowadzone w funkcji nie znajdują odzwierciedlenia w głównej funkcji. Co ja robię źle?Jak mieć wskaźnik char jako parametr wyjściowy dla funkcji C++

void SetName(char *pszStr) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    pszStr = pTemp; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char* pszName = NULL; 
    SetName(pszName); 
    cout<<"Name - "<<*pszName<<endl; 
    delete pszName; 
    return 0; 
} 

Odpowiedz

48

Twój wskaźnik jest kopiowany na stos i przypisujesz wskaźnik stosu. Jeśli chcesz zmienić wskaźnik, musisz przekazać wskaźnik do wskaźnika:

void SetName(char **pszStr) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    *pszStr = pTemp; // assign the address of the pointer to this char pointer 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    char* pszName = NULL; 
    SetName(&pszName); // pass the address of this pointer so it can change 
    cout<<"Name - "<<*pszName<<endl; 
    delete pszName; 
    return 0; 
} 

To rozwiąże Twój problem.


Istnieją jednak inne problemy. Najpierw wyłuskujesz wskaźnik przed wydrukowaniem. Jest to błędne, wskaźnikiem jest wskaźnik do tablicy znaków, więc chcesz wydrukować całą tablicę:

cout<<"Name - "<<pszName<<endl; 

Co masz teraz będzie po prostu wydrukować pierwszy znak. Also, trzeba użyć delete [] usunąć tablicę:

delete [] pszName; 

większych problemów, choć są w projekcie.

Ten kod to C, nie C++, a nawet wtedy nie jest standardowy. Po pierwsze, funkcja szukasz jest main:

int main(int argc, char * argv[]) 

Po drugie, należy użyć references zamiast wskazówek:

void SetName(char *& pszStr) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    pszStr = pTemp; // this works because pxzStr *is* the pointer in main 
} 

int main(int argc, char * argv[]) 
{ 
    char* pszName = NULL; 
    SetName(pszName); // pass the pointer into the function, using a reference 
    cout<<"Name - "<<pszName<<endl; 
    delete pszName; 
    return 0; 
} 

Poza tym, to zwykle lepiej po prostu wrócić rzeczy, jeśli potrafisz :

char *SetName(void) 
{ 
    char* pTemp = new char[10]; 
    strcpy(pTemp,"Mark"); 
    return pTemp; 
} 

int main(int argc, char * argv[]) 
{ 
    char* pszName = NULL; 
    pszName = SetName(); // assign the pointer 
    cout<<"Name - "<<pszName<<endl; 
    delete pszName; 
    return 0; 
} 

Jest coś, co czyni to wszystko lepszym. C++ ma string class:

std::string SetName(void) 
{ 
    return "Mark"; 
} 

int main(int argc, char * argv[]) 
{ 
    std::string name; 

    name = SetName(); // assign the pointer 

    cout<<"Name - "<< name<<endl; 

    // no need to manually delete 
    return 0; 
} 

Jeśli Oczywiście to wszystko może być uproszczone, jeśli chcesz:

#include <iostream> 
#include <string> 

std::string get_name(void) 
{ 
    return "Mark"; 
} 

int main(void) 
{ 
    std::cout << "Name - " << get_name() << std::endl;   
} 

Należy pracować na formatowaniu, aby rzeczy bardziej czytelny. Przestrzenie pomiędzy nimi swoimi operatorami pomaga:

cout<<"Name - "<<pszName<<endl; 

cout << "Name - " << pszName << endl; 

Podobnie jak w przestrzeniach pomiędzy angielskimi słowami pomaga, sodoesspacesbetweenyouroperators. :)

+2

+1, odpowiada na bezpośredni problem i wyświetla większy problem z kodem. –

+0

Dzięki GMan. To było naprawdę pouczające. – Mark

+0

Nie ma problemu :) – GManNickG

2

To, co piszesz, nie jest C++, ale kod C, który używa nowego zamiast malloc, i usuwa zamiast darmo. Jeśli naprawdę chcesz napisać kod w C++, zacznij od nowa. Przeczytaj książkę taką jak Accelerated C++, która nauczy Cię nowoczesnego idiomatycznego C++.

+0

To nie jest dokładnie odpowiedź na pytanie, ale jest to dobra sugestia ... – Zifre

+2

Ostatnia linia pytania brzmiała: "Co robię źle?" Myślę, że moja odpowiedź dokładnie to rozwiązuje. –

+0

Dzięki za sugestię. Zdecydowanie przejdę przez książkę. – Mark

4

Ponieważ jesteś oznaczony jako C++, czemu nie podać referencji std :: string i wypełnić go?

void GetName(std::string &strName) 
{ 
    strName = "Mark"; 
} 

Albo po prostu zwrócić std :: string:

std::string GetName2() 
{ 
    return "Mark"; 
} 

i nazywają to jak tak

std::string strName, strName2; 
GetName(strName); 
strName2 = GetName2(); 
assert(strName == "Mark"); 
assert(strName2 == "Mark"); 
//strName.c_str() returns the const char * pointer. 

Wtedy nie trzeba się martwić o uwolnienie żadnej pamięci.

+0

I nie zapomnij o #include :) –

7

Możesz także użyć odniesienia do wskaźnika w tym przypadku. Możesz również chcieć znać 2 inne błędy, które są w oryginalnym kodzie (zobacz moje komentarze w fragmencie kodu).

+0

Ładne złapanie w tablicy usunąć. – GManNickG

Powiązane problemy