char handling



  • char text[100];
    strcpy(text, "narf");
    strcpy(text, "hallo an alle");
    


  • Du hast einen Speicher reserviert, und willst da ne Zeichenkette reinquetschen die länger als der vorher reservierte Speicher ist. Zähl mal die Character nach! Das geht also so nicht, du mußt entweder selbst mehr Speicher für den String reservieren, und mit dem neuen String arbeiten oder am besten die Klasse std::string benutzen. Da kannst du das machen, was du ebend versucht hast, da std::string sich um die Speichereservierung für dich kümmert.



  • Hm, also für mich sieht das mehr nach C aus als nach C++...

    Devil



  • devil81 schrieb:

    Hm, also für mich sieht das mehr nach C aus als nach C++...

    Devil

    Oh! Dann bitte ich vielmals um Entschuldigung für das falsche Posten. 🙂

    @Artchi
    Hab es mit strings versucht und es geht. 😃



  • @odd
    Was hat das mit speicher reservieren zu tun ?

    char *text; 
    text="narf"; 
    text="hallo an alle";
    

    Er initialisiert nen Variable vom Typ zeiger auf Text,
    er weist der Variablen ne Adresse von nem konstanten string Im Konstanten-Speicher zu ...
    er weist der Variable nen anderen konstanten String zu ....

    @daishi
    es ist nur ein bisserl falsch, aber es ist nicht was du willst ...
    "narf" legt dir statisch ne Zeichenkette im konstanten speicher an, auf die nicht geschrieben werden kann. (eigenart des speicherbereichs)

    was miuch wundert, warum dein compiler nicht schon bei text="narf"; gemeckert hat. const char * auf auch char * duerfte nicht gehen !
    Wenns nen C Compiler ist, ists ne andere Sache, ich glaub die nehmen das mit const ned so genau ! Aber wenigstens ne Warnung ...

    Correkt waere .

    const char *text; 
    text="narf"; 
    text="hallo an alle";
    

    Obs sinn macht ist ne andere sache.

    Und du wuerdest kein Speicherfehler mehr bekommen, wenn mit strcpy auf dem konstanten String rumnuckelst ! sonder er wuerd gleich beim compilieren sagen, das er das ned mag ! :p

    Wennst wirklich nur die konstanten zeichenketten brauchst, wuerd ich mit unterschiedlichen zeigern arbeiten ....

    const char * t1 = "text1";
    const char * t2 = "text1";
    
    const char * t = NULL;
    
    if(mb_irgend_eine_Bedingung)
    {
        // Ab hier t1 benutzen 
        t = t1;
    }
    else
    {
        // ansonsten t2
        t = t2;
    }
    // und ab hier kannst immer schoen mit t arbeiten 
    // aber aufpassen, die zeichenkette auf die t zeigt ist konstant !
    

    Wenns den dynamisch brauchst (und den brauchst spaetestens, wenn strings aneinanderhaengen willst, oder einzelne buchstaben veraendern), wirst ned umhinkommen, den speicher zu malloc zu allocieren, Texte mit strcopy zu kopieren, und den speicher mit free wieder freizugeben ...

    Ciao ...



  • So, jetzt habe ich ein anders Problem.
    Den String kann ich mit cout nichtmehr ausgeben, da bekomme ich die nette Meldung:
    error C2679: Binaerer Operator '<<' : Kein Operator definiert, der einen rechtsseitigen Operator vom Typ 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' akzeptiert (oder keine geeignete Konvertierung moeglich) 😡



  • So, ich habe ne Lösung, die mich aber nicht befriedigt. 🙂
    Mit ner for-Schleife geht's

    for(i=0; i<str.size();i++)
      cout<<str[i];
    cout<<endl;
    

    Warum das andere nicht geht, ist mir unklar. Bei der CPP-Reference
    http://www.cppreference.com/cppstring.html
    steht es anders. ?????????????



  • Binde mal statt <string.h> die Datei <string> ein und schreib ein using namespace std; darunter! Dann kannst du auch direkt den std::string ausgeben.



  • Das hat leider keine Auswirkung auf das Problem. 😞



  • daishi schrieb:

    Das hat leider keine Auswirkung auf das Problem. 😞

    Hm, und <iostream> statt <iostream.h>? Ansonsten poste mal ein Minimalbeispiel, in dem es nicht geht.



  • So, hier nun wie erbeten ein kleines Beispiel:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string>
    using namespace std;
    ...
    int main(int argc, char* argv[])
    {
      string s1("hallo welt");
      cout<<s1<<endl;
      return 0;
    }
    


  • #include <iostream>
    brauch ich zumindest fuer cout und endl

    schenk dir dafuer stdio.h ...

    Ciao ...



  • <stdlib.h> kann in dem Beispiel genauso weg. Und wenn schon stdlib und stdio, dann bitte <cstdlib> und <cstdio> 🙂



  • Danke für die netten Ratschläge, was ich denn includen soll.
    Um weitere Bemerkungen zu verhindern, folgt hier der komplette def-Teil.

    #include "stdafx.h"
    #include"test.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream.h>
    #include <vector>
    #include <malloc.h>
    #include <string>
    #include <CString>
    using namespace std;
    #include <math.h>
    #include <cstdlib>
    #include <cstdio> 
    
    #define PI 3.1415926535897932384626433832795
    #define MAX_REAL 1.7976931348623158e+308	// größte pos. Zahl
    #define DBL_EPSILON 2.2204460492503131e-012 // kleinste positive Zahl x, bei der x+1.0 nicht gleich 1.0 ist. 
    #define Real double
    

    Das Problem besteht weiterhin.



  • daishi schrieb:

    Danke für die netten Ratschläge, was ich denn includen soll.

    Schade, dass du sie nicht befolgt hast...

    #include <iostream.h>
    

    🙄



  • ?
    Was soll die iostream? Die ist schon mit drin (5. Zeile von oben).
    Und ob ich es mit .h schreibe oder ohne hat keine Auswirkungen.



  • /bonk daishi

    Was soll die iostream

    Lies greundlicher ! 😃

    #include <iostream.h> -> #include <iostream>

    Hintergrund:

    iostream.h ist ne Headerdatei, die dir Kompatibilitaet zu C++ code aus frueheren zeiten ermoeglicht. Aus Zeiten, wo es noch keine namespaces gab.

    deshalb, includest du iostream.h, liegt cin,cout,cerr etc nicht im namespace std sondern im globalen.
    Fuer neue programme ist das schlecht !

    fuer neuere gibt es die iostream (ohne .h ) da liegt alles schoen sortiert im namespace std.
    Und wenn nicht jeder gleich std in den globalen namenspace einbinded, mittels using namespace std; dann macht das sogar sinn, weil man nen extra Qualifier fuer die Objecte nun hat ! :p
    Naja, fuer cin, cout, cerr eher weniger, da wird es keine weiteren definitionen geben, aber fuer allgemeinere dinge wie string list map etc ist das nen Vorteil, weil ist doof wenn fuer jede spezielle map nen die selbst entwickelst nen neuen namen suchen musst :p

    Ciao ...



  • @RHBaum
    😞 Ja, ich sollte lesen lernen. 😞
    Jetzt geht. 😮



  • Ok, dann weiter ...

    naechster Schritt, alle nicht benoetigten header entfernen ...

    Ich glaub C++ STL und malloc vertragen sich ned so richtig, zumindest fuer nicht-Profis. Ich nehm mal an, Du willst keine klasse mit eigener Speicherverwaltung (new operator selbst definieren) entwickeln ...

    Ciao ...



  • Die anderen includes müssen drin bleiben, ich brauchte nur eine Möglichkeit, wie ich die Daten aus einer Datei in einen String schreiben und dann für den jeweiligen Bedarf manipulieren kann.

    Das (böse böse)malloc brauche ich, um meine Datenstruktur den Bedürfnissen anzupassen. (new ist zu umständlich, da dort kein realloc vorhanden)


Anmelden zum Antworten