Typkonvertierung(double, (const) char) und strlen

Hallo ihr Experten da draußen :wink:.
Im Rahmen meiner schulischen Ausbildung absolviere ich gerade ein Praktikum in einer Firma und bin im moment im Bereich C(++) Programmierung hängen geblieben.
Ich habe schon ein paar Grunderfahrungen in der Schule im Umgang mit C++ gesammelt, aber ich würde mich trotzdem noch als ziemlich Anfänger bezeichnen (findet mein Chef auch :wink:).
Ich schreibe derzeit ein Programm zum Bar Codes scannen und hänge im moment an der Prüfroutine für die Länge einer Nummer.
Es soll ein Code geprüft werden, den der Benutzer einscannt und der 6 Zeichen lang ist, ein Beispiel wäre dafür 411740.
Am Anfang habe ich diesen global als double deklariert und bisher funktionierte es auch alles ganz gut.
Jetzt wollte ich die Prüfschleife zur Längenprüfung in folgender Form schreiben:

if(strlen(edp) = 6)
{
cout

Hallo Fragewurm,

Ich habe schon ein paar Grunderfahrungen in der Schule im
Umgang mit C++ gesammelt, aber ich würde mich trotzdem noch
als ziemlich Anfänger bezeichnen (findet mein Chef auch :wink:).

Und ich auch !

Am Anfang habe ich diesen global als double deklariert und
bisher funktionierte es auch alles ganz gut.

Du solltest einmal das Kapitel mit den Datentypen durchlesen:
char, short, int und long sind Ganzahlwerte (Integer).
float und double sind Fliesskomma-Werte.
Und Zeichenketten (Strings) werden aus char zusammengesetzt.

Jetzt wollte ich die Prüfschleife zur Längenprüfung in
folgender Form schreiben:

if(strlen(edp) = 6)

strlen funktioniert NUR mit Zeichenketten !!

‚strlen‘ : Konvertierung des Parameters 1 von ‚double‘ in
‚const char *‘ nicht moeglich

Da hatder Compiler absolut recht !!

Ich habe schon versucht, den Wert oben als char, const char*
und ähnliches zu deklarieren, aber es führte irgendwie alles
zu einem Fehler in ähnlicher Form.

Tja, denn sie wissen nicht was sie tun …

… ich leider auch nicht, weil aus deinem Beispiel nicht hervorgeht wie edp überhaupt declariert wurde.

Zudem solltest du das Ganze sowieso nicht mit FLiesskomma (double) machen, weil es da Rundungs-Probleme geben kann und ein Barcode hat num einmal keine Nachkomma-Stellen.

Also lerne zuerst einmal den Unterschied zwischen den Datentypen.

MfG Peter(TOO)

also, edp ist als double deklariert, deswegen will der compiler ja überhaupt erst die konvertierung von double nach const char* machen.
ich hab’s eben mal mit der edp deklaration von edp als long int versucht und dann direkt vor der if schleife den wert zu char konvertiert.
das funktionierte meines erachtens auch alles soweit (jedenfalls hat der compiler nichts zu meckern gehabt), allerdings bleibt das problem weiterhin, dass er jetzt edp2 nicht von char zu const char* konvertieren will.

Bitte Bitte Bitte !!!
Hallo Fragewurm,

Lerne bitte zuerst die Basics, die stehen in jedem C/C++ Handbuch drin. Hier wird wohl keiner die Lust haben irgendwelche Grundlagen-Kurse abzutippen.

Also nochmal zum mitlesen:

  1. Werde dir klar darüber was die einfachen Datentypen sind und welcher Unterschiede es gibt.
  2. cout kennt verschiedene Formattierungen, die muss man halt auch kennen. Meistens kommen die gleich ein paar Seiten nach dem „Hello word“ Beispiel.

MfG Peter(TOO)

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Lotex

Es soll ein Code geprüft werden, den der Benutzer einscannt
und der 6 Zeichen lang ist, ein Beispiel wäre dafür 411740.

„6 Zeichen“ bedeutet bei Ganzzahlen:

  • größer gleich 100,000
  • kleiner gleich 999,999

Am Anfang habe ich diesen global als double deklariert und
bisher funktionierte es auch alles ganz gut.
Jetzt wollte ich die Prüfschleife zur Längenprüfung in
folgender Form schreiben:

Die „Länge“ einer ‚double‘ zahl ist 64 Bit, also 8 Byte.
Immer! Da läßt sich nichts prüfen.

Was man prüfen kann ist: die Anzahl der Ziffern, wenn
man die Zahl hinschreibt. Z.B.:

 char nummer[] = "123123";

Hier haben wir nur Text und keine
Zahl (muss man erst umwandeln).

if(strlen(edp) = 6)

In C/C++ ist:
= immer eine Zuweisung
== immer ein Vergleich

Nach obiger Erkenntnis wäre also diese Form korrekt:

 if(strlen(nummer) **==** 6)

Jetzt sagt mir das Programm (ich benutze übrigens die Visual
C++ Autoren Version):
‚strlen‘ : Konvertierung des Parameters 1 von ‚double‘ in
‚const char *‘ nicht moeglich

Weil strlen(char *parameter) einen „Parameter“ vom
Typ char* verlangt - und nicht „double“.

Ich habe schon versucht, den Wert oben als char, const char*
und ähnliches zu deklarieren, aber es führte irgendwie alles
zu einem Fehler in ähnlicher Form.

Du könntest unsere eingangs gewonnene Erkenntniss
nutzen und schreiben:

 if(edp \>= 100000 && edp ... allerdings nur, wenn es sich immer
nur um Zahlen und keine Buchstaben handelt bzw.
keine führenden Nullen drin sind :wink:

Woher bekommst Du denn edp? Wie sieht die Quelle aus?

Grüße

CMБ

Danke für die, sogar für Anfänger verständliche, Erläuterung Semjon, aber hab inzwischen meinen Kopf ma angesrengt und mein programm umgeschrieben, sodass es passt.
@Peter: Danke, ich weiss was für datentypen es gibt, wie groß der speicher ist und was sie enthalten dürfen, mir war nur nicht bewusst, dass man mit strlen nichts außer char variablen prüfen kann.
dachte das wäre möglich, aber nun gut.
alles in allem hätte es eine etwas weniger von oben herab schreibweise auch getan.

Nochmal zu deiner Frage Semjon:

Inwiefern Quelle?
Ich denk mal du meinst wo ich den herbekomm oder?
Den scan ich aus einem Bar Code ein

Hallo,

Inwiefern Quelle?
Ich denk mal du meinst wo ich den herbekomm oder?
Den scan ich aus einem Bar Code ein

Wie konkret?

Die Zeile mit der Zuweisung: edp = …
und die zwei Zeilen davor :wink:

Grüße

CMБ

Wie konkret?

Die Zeile mit der Zuweisung: edp = …
und die zwei Zeilen davor :wink:

Grüße

CMБ

char edp; - deklaration
cin >> edp; - eingabe
if(strlen(edp) == 6)
{
cout

Hallo Lotex,

Versuch mal statt:

char edp; - deklaration
cin >> edp; - eingabe
if( strlen (edp) == 6)


Und das wäre meine Schleife.

sowas:

 #include 
 #include 
 using namespace std;

 ...
 **string** edp; // deklaration
 cin \>\> edp; // eingabe

 if( edp. **length** () == 6 ) {
 cout ... denn in ein "char" kann von cin nur
ein Zeichen eingelesen werden.

Grüße

CMБ

Danke für den Tip, aber using namespace std; funzt bei mir irgendwie nicht, kA warum nicht. In der Schule ging’s immer, aber hier und bei der Arbeit…no way.
Hab die Deklaration aber auch etwas abgewandelt, hab jetzt char edp[7]; stehen, das haut auch hin.
Das einzige was mir im Moment noch fehlen würde, wäre eine variable Ausgabe, die der Benutzer bei Bedarf auch ändern kann.
Am Ende sollen ja EDP + TAN Code in eine Datei geschrieben werden und mein Chef will ne Vorgabe, also z.b. als Angabe TAN + EDP Codes.txt oder sowas in der Art.
Mit normalen Ausgaben läuft’s aber so nicht, also muss ich weiter suchen :wink:.

Moin,

ich nochmal.

Ich habe jetzt soweit alles hinbekommen was ich realisieren wollte, aber im moment stehe ich vor einem Problem auf dass ich (für meine Sache) nicht den geringsten Ansatz habe.
Ich will in mein Programm eine Vergleichsfunktion einbauen, sprich die Datei die ich schreibe soll, bevor sie gespeichert wird, mit einer anderen Datei(ich nenn sie mal Masterdatei) abgeglichen werden.
Wenn der gescannte EDP + TAN Code in der Master Datei richtig gefunden wurde, sollen die Datei in die neue Datei geschrieben und die Datei gespeichert werden.
Meine Idee wäre hierbei, ob es nicht möglich wäre, innerhalb des Programms die Masterdatei zu öffnen und dann mit einem entsprechenden Befehl die Strings zu vergleichen.
Ich stehe hierbei vor der Frage, was für einen Befehl ich dann dafür nehmen könnte. Strcmp vielelicht?
Ich habe in meinen Büchern („C Programmieren von Anfang an“ und „C++ Schritt für Schritt“), sowie bei google nichts passendes für C/C++ gefunden, lediglich fertige Programme in exe Form, Möglichkeiten für Excel, PHP oder VB.
Gibt es sowas in der Form in C/C++ überhaupt?

Hallo lotex

Wenn der gescannte EDP + TAN Code in der Master Datei richtig
gefunden wurde, sollen die Datei in die neue Datei geschrieben
und die Datei gespeichert werden.

Wie sehen denn solche Dateien aus. Kannst Du mal
eine komplett (oder ein Stück) hier reinschreiben?

Ansonsten ist das geschilderte Problem in C/C++ mit
Sicherheit zu lösen. Wir können es ja so handhaben,
dass einer, der das schon mal gemacht hat, Dir einen
klitzekleinen Tippgibt - damit Du das dann selber
hinbekommst.

Grüße

CMБ

Hallo Semjon,

Ich habe dabei keine Vorgabe bekommen in welcher Form das sein soll.
Ich habe es so gemacht, dass die Datei angelegt wird, sofern sie nicht vorhanden ist und die Daten in folgender Form gespeichert werden:
EDP TAN
Also z.b. 111111 AAAA-AA-AA-AA-111-11-111-1111

Im einen Fall ist der Dateiname „Datum“.txt (über __DATE__) und im anderen Fall kann der Benutzer den Namen selbst eingeben.

Hallo Lotex

Also z.b. 111111 AAAA-AA-AA-AA-111-11-111-1111

Im einen Fall ist der Dateiname „Datum“.txt (über __DATE__)
und im anderen Fall kann der Benutzer den Namen selbst
eingeben.

folgende Vorgehensweise würde ich vorschlagen

#1 - Öffnen (für lesen) und Einlesen der Master-Datei

  • Jede Zeile in eine Zeichenkette einlesen ( string oder char [NN]
  • Zeichenketten sind als Feld organisiert, (vector oder char*[LL])
  • Master schliessen

#2 öffnen der neuen Datei (für schreiben)

#3 neue Daten eingeben und testen

  • über eine Schleife mit dem Master-Feld vergleichen
  • Daten als zeile in neue Datei schreiben
  • Datei schliessen

Oder so ähnlich

Grüße

CMБ

Hallo Semjon,

das wäre eine Möglichkeit, um einzelne parts vergleichen zu können, allerdings sind in so einer Datei meist ein paar Hundert TANs + EDPs enthalten und die alle gleichzeitig bzw nacheinander einzulesen wäre ja recht zeitaufwendig oder nicht?

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Lotex

#1 - Öffnen (für lesen) und Einlesen der Master-Datei

  • Jede Zeile in eine Zeichenkette einlesen ( string oder
    char [NN]
  • Zeichenketten sind als Feld organisiert,
    (vector oder char*[LL])
  • Master schliessen

das wäre eine Möglichkeit, um einzelne parts vergleichen zu
können, allerdings sind in so einer Datei meist ein paar
Hundert TANs + EDPs enthalten und die alle gleichzeitig bzw
nacheinander einzulesen wäre ja recht zeitaufwendig oder
nicht?

Ich habe die Erfahrung gemacht, dass auf normalen
Computern das Einlesen von Dateien von wenigen MB
Größe in einer Sekunde erledigt ist.

Nehmen wir mal an, ein solcher Code pro Zeile
hat 32 Byte (incl. Zeilenwechsel). Wenn Du eine
Datei mit 100,000 Datensätzen hast, sind das
insgesamt 3 MB. Diese Datei ist in einer Sekunde
eingelesen:

 #include 
 #include 
 
 #define MINCODELENGTH 10 // wie lang muss ein code mindestens sein
 #define MAXCODES 100000 // wie viele codes sind maximal zu erwarten

 char \*codetab[MAXCODES]; // in diese Tabelle kommen die Codes
 int ncodes = 0; 

 void einlesen( ... )
{
 int i, len;
 char zeile[80];
 char filename[80] = "aaabbbccc.dat";

 FILE\* fstr = fopen(filename, "rt");
 // Datei zeilenweise einlesen und Code
 // in Tabelle kopieren
 while( fgets( zeile, sizeof(zeile), fstr ) != 0) {
 if( (len=strlen( zeile )) \>= MINCODELENGTH ) {
 codetab[ncodes] = new char [len+1];
 strcpy( codetab[ncodes], zeile );
 ++ncodes;
 }
 }
 fclose(fstr);

 // gelesene Werte testweise ausgeben
 for (i=0; i %s \n", i+1, codetab[i]);
 }
 
 ...

Grüße

CMБ

Hallo Lotex

das wäre eine Möglichkeit, um einzelne parts vergleichen zu
können, allerdings sind in so einer Datei meist ein paar
Hundert TANs + EDPs enthalten und die alle gleichzeitig bzw
nacheinander einzulesen wäre ja recht zeitaufwendig oder
nicht?

Wie schon geschrieben ist es bei ein „paar Hundert“ Datensätzen das schnellste die ganze Datei im Speicher zu halten. Zugriffe auf den Hauptspeicher sind etwa 10’000 mal schneller als auf Disk.

Wenn die Datei beliebig gross sein soll, bleibt nur noch das Ablegen auf der Platte übrig, du hast also ein klassisches Datenbank-Problem.

Hier kommst du nur noch mit sortieren der Daten weiter.

  1. Du kannst die Daten nach der Häuffigkeit ihres Auftretens sortieren und linear suchen.
  2. Du sortierst die Daten nach dem Wert und kannst dann binär suchen (Zuerst liest du den mittleren Datensatz ein (Also bei 100 Datensätzen, Datensatz 50) und vergleichst ihn mit dem zu suchenden Wert. Ist der Wert identisch -> Volltreffer. Wert kleiner als Datensatz -> der gesuchte Datensatz befindet sich im Bereich 1 bis 49, also liest du nun Datensatz Nr. 25, andernfalls liegt der Gesuchte Wert zwischen Datensatz 51 und 100, also 75 einlesen. Das machst du solange bis du den Datensatz gefunden hast oder keiner mehr übrigbleibt.).
  3. Hash-Werte. Du bildest aus dem Wert einen Hash-Wert, womit du dann über eine Tabelle direkt den richtigen Datensatz finden kannst.

MfG Peter(TOO)

Hallo Fragewurm,

Hab die Deklaration aber auch etwas abgewandelt, hab jetzt
char edp[7]; stehen, das haut auch hin.

Aber nur bei schönem Wetter !!!
Wenn mal einer einen Code einliest der länger als 7 Zeichen ist, stürzt dein Programm ab (Bufferoverflow) oder du bekommst gar nicht mit, dass der Code länger ist.

MfG Peter(TOO)

Moin,

ich bin’s nochmal zum vorerst letzten Mal.
Mein Praktikum endet heute und ich habe mein Programm erfolgreich fertig gestellt.
Ich wollte den Thread hier aber nicht so stehen lassen, ohne mich noch einmal für die Hilfe zu bedanken.
Also, Danke für die Hilfe Leute, macht’s gut und weiterhin viel Spaß in den Welten der Programmierung :wink:.

Greetings

Lotex