Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Große Schwierigkeiten

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
04.11.2007, 18:24 Uhr
~blurry333
Gast


Hallo!!

Kann mir bitte jemand helfen.
Es geht um folgende Aufgabe:

In einer Funktion void str_add(char** s1, char* s2) soll s2 an s1 angehängt werden. Der Speicher für diesen String s1wird dynamisch erweiter damit er den String s1 aufnehmen kann. Damit im Aufrufprogramm die Variable, die auf s1 zeigt auf den erweiterten String zeigt, muss die Adresse der Variablen übergeben werden.

Und hier meine Lösung die leider so nicht stimmt.

C++:
#include <conio>
#include <iostream>
#include <stdlib>

void str_add(char** s1,char* s2)
{  int i;int j;
     char* tmp=new char[100];
    
     for( i=0;*s1[i];i++)
     {tmp[i]=*s1[i];}
    
     for(j=0,i=i+1;s2[j];i++,j++)
     {tmp[i]=s2[j];}

     s1=&tmp;
}


void main(void)
{
  
    char* s1[10]={"Aber"};
    char* s2[11]={"Hurtig"};
    
   cout<<str_add(&s1,s2);


getch();

  }


Dieser Post wurde am 04.11.2007 um 19:31 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
04.11.2007, 19:32 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Das mit dem "dynamisch erweitern" kann nur klappen wenn du den übergebenen speicher auch mit new (malloc) allokierst. sonst darfst du da nicht drin rumpfuschen...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
04.11.2007, 19:40 Uhr
~blurry333
Gast


Hab ich doch gemacht.

char* tmp = new char[100];
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
04.11.2007, 19:45 Uhr
0xdeadbeef
Gott
(Operator)


Oh Junge...wer hat dir den sowas beigebracht...

Aaaalso, erstmal die offensichtlichen Dinge:

- <stdlib> ist kein header, das muss wenn, dann <cstdlib> heißen.
- <conio> ist ein hier äußerst unnötiger Nicht-Standardheader (Nimm statt getch() einfach std::cin.get())
- main ist immer int. Schreib int main(), per default gibt main (aber auch nur main!) 0 zurück.
- Symbole aus Standardheadern sind im Namensraum std. std::cout, std::cin, std::endl, std::string etc. Ich empfehle ernsthaft, das auszuschreiben, aber wenn's dir partout zu viel Tipparbeit ist, schreib "using namespace std;" An den Anfang deiner main-Funktion.

Die im echten Leben sinnvolle Variante wär hier natürlich, std::string zu benutzen, also

C++:
#include <iostream>
#include <string>

int main() {
  std::string s = "Aber";

  s += " hurtig";

  std::cout << s << std::endl;
}


...aber hier geht es wohl um eine Zeigerübung. Ich werd dir nicht die gesamte Lösung vorkauen, aber hier ein paar Tipps:

1. Wenn du etwas mit new[] anlegst, musst du es auch mit delete[] wieder freigeben
2. Eine lokale Variable zu verändern, ändert die außerhalb übergebene Variable nicht - &s1 in main in deinem Beispiel wird nach Ablauf der str_add-Funktion immer noch das gleiche sein. Aber Du kannst an die Entsprechende Stelle im Speicher schreiben und damit s1 verändern. Vergleiche zum Beispiel

C++:
void quadratieren_nach_altem_c_stil(int *x) { *x *= *x; }


3. Bevor du den Speicher anforderst, musst du herausfinden, wie viel Speicher du eigentlich brauchst - also die Länge der beiden Strings plus Sentinel. Erst dann kannst du per new die angemessene Speicherlänge alloziieren. Vergiss dabei nicht, den alten Speicher freizugeben (siehe 1)
4. std::strcpy aus dem Header <cstring> ist dein Freund. In deinem Beispiel vergisst du den sentinel, die alten Funktionen da übernehmen das für dich.
5. Diese Funktion kann in der Form eigentlich nur funktionieren, wenn du von vorneherein als ersten Parameter einen Zeiger auf einen mit new[] angeforderten Speicherbereich, oder einen Zeiger auf einen Zeiger auf NULL übergibst, sonst kriegst du entweder Speicherlöcher oder falsche delete[]s.

Nachtrag:

C++:
tmp = new char[100];


ist nicht dynamisch. 100 war das letzte mal, als ich gekuckt habe, eine Konstante.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 04.11.2007 um 19:49 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
04.11.2007, 19:49 Uhr
mischa
Fragender


Hallo
mit was compilierst du diesen Code? Besorg dir einen aktuellen Compiler. Den neusten g++ oder MVS 2005 Express, gleich als IDE
--
Latein Unterricht ist die spätere Rache der Römer an den Germanen.

Dieser Post wurde am 04.11.2007 um 19:52 Uhr von mischa editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
04.11.2007, 19:52 Uhr
0xdeadbeef
Gott
(Operator)


Würd mich nicht wundern, wenn das Visual "C++" 6.0 wäre, oder etwas in der Größenordnung. Ich hab ein bisschen den Verdacht, dass die Lehrer keinen Bock haben, C++ wirkllich zu lernen, und deshalb den einzigen "Compiler" nehmen, der ihren kaputten Code überhaupt noch übersetzt

Dass es sich dabei nicht um einen C++-Compiler im eigentlichen Sinne handelt, ist dann nebensächlich, Hauptsache der alte C-mit-Klassen-Code kompiliert noch. *seufz*
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
04.11.2007, 22:23 Uhr
~blurry333
Gast


Das wäre die Lösung, sie funktioniert zum Beispiel im Borland Compiler.

C++:
#include <conio>
#include <iostream>
#include <stdlib>

char * input(char* hw) {
  char * x;

  x = new char[4096];

  cout << hw;
  cin >> x;

  char * neu;

  neu = new char[strlen(x) + 1];

  strcpy(neu, x);

  for(int i = 0; neu[i] = x[i]; i++);

  delete [] x;

  return neu;
}

void str_add(char** s1,char* s2) {
  int i;
  int j = 0;

  char* tmp = new char[strlen(*s1) + strlen(s2) + 1];

  for(i = 0; *(*s1 + i); i++) {
    tmp[i] = *(*s1+i);
  }
    
  for(; s2[j]; j++) {
    tmp[i + j] = s2[j];
  }

  delete[] *s1;

  *s1 = tmp;
}

int main(void) {
   char* s1;
   char* s2;

   s1 = input("String1: ");
   s2 = input("String2: ");

  str_add(&s1, s2);

  cout << s1;

  getch();
}



Bearbeitung von 0xdeadbeef:

cpp-tags eingefügt, Einrückung. Nächstes mal selbst machen.


Dieser Post wurde am 04.11.2007 um 23:44 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
04.11.2007, 23:54 Uhr
0xdeadbeef
Gott
(Operator)


Da kommen wir der Sache doch schon näher. Wenn der Borland-Compiler das so akzeptiert, muss er allerdings ziemlich kaputt sein - standardkonform sieht das so aus:

C++:
#include <iostream>
#include <cstdlib> // für system, siehe unten
#include <cstring> // für strcpy etc.

char *input(char const *hw) {
  char x[4096]; // Kein Grund, hier den Heap zu bemühen

  std::cout << hw;
  std::cin.getline(x, 4096);

  char *neu;

  // Alle Symbole der Standardbibliothek sind im namespace std
  neu = new char[std::strlen(x) + 1];

  std::strcpy(neu, x);

  // Die Schleife hier ist dann unnötig, std::strcpy macht das für dich

  return neu;
}

void str_add(char **s1, char *s2) {
  int i, j = 0;

  char *tmp = new char[strlen(*s1) + strlen(s2) + 1];

  std::strcpy(tmp, *s1);
  std::strcat(tmp, s2);

  delete[] *s1;

  *s1 = tmp;
}

int main() {
   char *s1;
   char *s2;

   s1 = input("String1: ");
   s2 = input("String2: ");

  str_add(&s1, s2);

  std::cout << s1 << std::endl;

  delete[] s1;
  delete[] s2;

  // Da es sich hier nur um einen dreckigen Hack für die gängigen Windows-IDEs handelt,
  // bevorzuge ich hier diese Variante. Keine Probleme mit Artefakten im Eingabestrom etc,
  // und rausnehmen musst dus vor der Auslieferung im Zweifel eh.
  // Möglich wäre auch
  // std::cin.get();
  // respektive
  // std::cin.ignore();
  // aber das hier ist am einfachsten.
#ifdef _WIN32
  std::system("pause");
#endif
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: