Hallo leute!
Versuche seit einigen Stunden vergeblich zu einer Lösung meines Problems
zu kommen. Aber was ich auch probiert habe, es funktioniert nicht.
Ich hoffe von euch kann mir wer helfen?
Hier mein Problem:
Ich lese eine Datei zeilenweise ein, und speichere jede zeile immer in
ein Array. in dieser Datei werden allerdings alle Kommazahlen mit einem
"," geschrieben. Damit das C-Programm diese als Kommazahlen erkennt muss
ich nun alle "," durch "." ersetzen.
sollte das nicht so funktionieren:
char Line[120] = "eingelesene,Zeile";
Line = Line.Replace("," , ".");
Bei mir funktioniert das jedenfalls nicht könnte mir da jemand
weiterhelfen und mir eine andere Methode zeigen oder mich auf meine/n
Fehler hinweisen.
Bitte berücksichtigt dass ich noch ein blutiger Anfänger bin was
C-Programmierung angeht.
mfg. Reini
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
Bittesehr. > Ich lese eine Datei zeilenweise ein, und speichere jede zeile immer > in ein Array. Musst du nicht, Kannst auch nen ret = fread(...) machen, da stehen dann die Newlines als CR, LF oder CRLF drin. Zum Ersetzen von Zeichen ist das völlig unerheblich, und du bist damit schneller.
Danke erstmlal. Ich werde nun mal versuchen das umzusetzen.
Gast
#2326833
Hallo Reini, verwechselst du gerade C und C#? Was du da vor hast, geht nicht. Line ist ein Array aus chars und kennt daher keine Methode "Replace". Hier eine kleine Funktion, mit der du das machen kannst:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Der Aufruf in deinem Fall:
1 | |
VG Thomas
Gast
#2326834
Reinhard Leitgeb schrieb: > sollte das nicht so funktionieren: > > char Line[120] = "eingelesene,Zeile"; > Line = Line.Replace("," , "."); Das ist kein C, sondern C++ oder eine andere objektorientierte Variante. In Standard C würdest du eine Funktion selbst schreiben (so wie Thorsten) und ggf. Funktionen aus der Standardbibliothek /string.h/ verwenden. > Bei mir funktioniert das jedenfalls nicht könnte mir da jemand > weiterhelfen und mir eine andere Methode zeigen oder mich auf meine/n > Fehler hinweisen. Was sagt denn dein Compiler zu deinem Code??? > Bitte berücksichtigt dass ich noch ein blutiger Anfänger bin was > C-Programmierung angeht. Kein Problem, wir haben alle mal klein angefangen. Was ich aber sehr empfehlen kann: Beginne mal mit einem Buch über C, wie dem Klassiker von K&R: http://en.wikipedia.org/wiki/The_C_Programming_Language MFG Helfer
Du liesst deine Zeilen warscheinlich mit fscanf(...) ein. Bei einigen wenigen Daten ist das durchaus ok. Ich habe einen XML Reader/Interpreter/Codegenerator geschrieben, und dem gleich mehrere Streams verpasst. Im Reader selbst brauche ich zwar alles zeichenweise, aber meine interne GetNextChar() stuppst einen Loader an, der sich die nächsten 5MB des Files automatisch reinzieht. Enormer Performancegewinn. Hier geht es aber auch um 3-20MB/XML File, bzw. >500MB insgesamt. Genauso verhält es sich mit meiner Ausgabe in Files. Ich dachte, dass Windows das Streaming von Files bereits selbst macht, aber das scheint nicht der Fall zu sein. Vielleicht kann man das auch irgendwie aktivieren, oder andere Funktionen nutzen, ka, ich bin bei fread/fwrite geblieben und mache die Bufferung selbst. In/Output "vernünftig" zu buffern bringt nen enormen Performanceschub.
>Was sagt denn dein Compiler zu deinem Code???
Ich bekomme folgende Fehlermeldung:
error C2228: left of '.Replace' must have class/struct/union type
Wisst ihr zufällig wie ich dieses problem behandeln soll?
Random ... schrieb: > Du liesst deine Zeilen warscheinlich mit fscanf(...) ein. Warum sollte man das tun? Mit fgets() kann man problemlos zeilenweise le_s_en (ein s).
Gast
#2326865
den Aufwand kannst Du DIr sparen. google mal unter 'c++ culture' , da wird Dir gezeigt wie amerikanische Zahlen ( mit . halt ) in einem 'deutschen' Programm eingelesen werden können , das deutsche Programm verlangt hat ',' .
Rufus Τ. Firefly schrieb: > Random ... schrieb: >> Du liesst deine Zeilen warscheinlich mit fscanf(...) ein. > > Warum sollte man das tun? Mit fgets() kann man problemlos zeilenweise > le_s_en (ein s). Reinhard Leitgeb schrieb: > Bitte berücksichtigt dass ich noch ein blutiger Anfänger bin was > C-Programmierung angeht. deshalb :-) printf und scanf sind idR. die ersten IO Funktionen, die man beim Lernen von C "zu Gesicht" bekommt. Oder halt cin/cout, wobei ich mich mit den Dingern nie anfreunden konnte. Die sind ja auch C++, wobei C/C++ vielfach durcheinanderzermischt wird... Ich bevorzuge fread/fwrite BIN/ASCII, je nach Bedarf :-)
Martin schrieb: > den Aufwand kannst Du DIr sparen. > > google mal unter 'c++ culture' , da wird Dir gezeigt wie > amerikanische Zahlen ( mit . halt ) in einem 'deutschen' Programm > eingelesen werden können , das deutsche Programm verlangt hat ',' . Du kannst das auch mit Klassen in C++ realisieren, z.B. mit CString unter MS VC. CString bringt dann glaub ich auch so replacer mit. Benutze ich aber nicht, ist mir alles zu langsam und zu viel Overhead :-)
Reinhard Leitgeb schrieb: > Wisst ihr zufällig wie ich dieses problem behandeln soll? So wie Random ... in seinem ersten Beitrag geschrieben hat: Schreib Replace als Funktion, bei der der zu bearbeitende String als Argument übergeben wird. Übrigens kannst du dir auch mal die Funktion setlocale der C-Standard- bibliothek anschauen. Damit kannst du das Verhalten von scanf, printf usw. landesspezifisch einstellen. Das ist vor allem dann sinnvoll, wenn die Datei mit den Kommata als Dezimaltrennzeichen auf dem gleichen PC erstellt wird, auf dem auch dein C-Programm läuft. Mit
1 | |
wird das vom Benutzer als Default definierte Locale (in Windows Länder- einstellungen), also u.a. auch das richtige Dezimaltrennzeichen für Ein- und Ausgaben verwendet. Auch das Datumsformat, die Sortierreihenfolge von Strings uvw. werden davon beeinflusst. Sollen allerdings nur beim Einlesen von Zahlen (nicht bei der Ausgabe) Kommata als Dezimaltrennzeichen verwendet werden, und ist sicherge- stellt, dass wirklich jedes in der Datei vorkommende Komma ein Dezi- maltrennzeichen ist, ist die Konvertierung mit der /Replace/-Funktion praktischer, weil sie unabhängig vom eingestellten Locale funktioniert und sowohl Kommate als auch Punkte zulässt. Random ... schrieb: > Im Reader selbst brauche ich zwar alles zeichenweise, aber meine > interne GetNextChar() stuppst einen Loader an, der sich die nächsten > 5MB des Files automatisch reinzieht. Das ist eigentlich genau das, was die Funktionen fread, fscanf, fgetc usw. sowieso schon tun, deswegen werden sie auch von "buffered I/O functions" genannt. Evtl. musst du mit setvbuf die Puffergröße und -charakteristik deinen Wünschen anpassen.
Gast
#2326898
Schau Dir an was deine Umgebung an "Regular Expressions"-Funktionalitäten im Angebot hat, das ist eines der Werkzeuge die man kennen sollte wenn man viel mit Textdaten hantieren muss. Sonst gibt es auch noch eine freie Bibliothek namens PCRE...
Yalu X. schrieb: > Das ist eigentlich genau das, was die Funktionen fread, fscanf, fgetc > usw. sowieso schon tun, deswegen werden sie auch von "buffered I/O > functions" genannt. Evtl. musst du mit setvbuf die Puffergröße und > -charakteristik deinen Wünschen anpassen. Stimmt, da war was :-) Da hab ich mich beim retargeting der ARM <stdio> auf ein eigenes virtuelles Filesystem mal mit rumgeärgert **g** Beim retarget-Ziel "UARTn" soll der ja nicht buffern, sondern jedes Zeichen rausschieben ans Terminal. Trotzdem bleib ich bei meinem eigenen Buffer, der ist "dichter dran" und einfacher anzupassen :-)
Reinhard Leitgeb schrieb: > Ich bekomme folgende Fehlermeldung: > > error C2228: left of '.Replace' must have class/struct/union type > > Wisst ihr zufällig wie ich dieses problem behandeln soll? Indem du dir überlegst, dass es in C keine Klassen und daher auch keine Methoden innerhalb von Klassen gibt. Etwas von der Form a.b (welches keine Gleitkommazahl ist), kann in C nur eine Struktur sein. a ist der Variablenname der Struktur und b ist der Name der gewünschten Komponente der Struktur. Hast du eine Struktur? Nein! Du hast ein Array. Also kann die Syntax Line.Replace schon mal nicht richtig sein. Wie du dieses Problem behandeln sollst? Indem du jetzt endlich einmal anfängst ein C-Buch von vorne bis hinten durchzuackern! Das ist ja nicht das erste mal, dass du hier eklatantes Nichwissen von absoluten Grundlagen zeigst und es wurde dir schon oft genug nahegelegt, dass du mit dem Lesen eines Buches anfangen musst. Tu es endlich! Du wirst aus deinem Viertelwissen nie herauskommen, wenn du nicht anfängst, dir die Sprache, ihre Möglichkeiten und ihre Syntax systematisch beizubringen. Durch immer wieder Aufschnappen von Brocken in Foren wird das nichts werden. Das hat noch bei keinem Neuling funktioniert und bei dir funktioniert es erst recht nicht. > Bitte berücksichtigt dass ich noch ein blutiger Anfänger > bin was C-Programmierung angeht. Eine Zeitlang kriegst du diesen Bonus. Aber irgendwann ist schluss. Irgendwann heißt es dann: Warum tust du eigentlich nicht, was dir schon viele nahegelegt haben? Wer einmal als Flachlandtiroler mit Sandalen in die Berge geht und von der Bergwacht gerettet werden muss, hat einen gut. Wer es aber ständig tut, muss damit rechnen, dass ihn dieses Verhalten irgendwann als "resistenter Wiederholungstäter" teuer kommt. Das andere, was ich aus der Fehlermeldung herauslesen kann: Du verwendest einen C++ Compiler. Man kann einen C++ Compiler als eine Art 'besseren C-Compiler' benutzen, wenn man sich bewusst ist, dass es im 'C-Teil' von C++ Unterschiede zu C gibt. Dessen ist man sich aber nur dann bewusst, wenn man C auch wirklich beherrscht. Daher ist es für Anfänger allemal besser, erst einmal mit einem richtigen C-Compiler an die Sache heranzugehen und nicht von einem C++ Compiler nur den 'C-Teil' zu benutzen.
Gast
#2328134
http://blog.plover.com/2006/09/11/ ziemlicher AHA-Effekt was C vs C++ angeht. ... Ein anderes Gedankenspiel welches hilft C-Arrays zu verstehen: Warum sind a[i] und i[a] in C identisch?
>a[i] und i[a] in C identisch?
(ich hab ja GOTT SEI DANK NIX mit C zu tun..)
was erwartest für Antwort:
weil a und i einfach zusammengezählt werden
stimmt aber vermutlich nur bei byte und char array...
bei einem array mit Integern wird es nicht funktionieren?!?
Robert L. schrieb: > stimmt aber vermutlich nur bei byte und char array... nein , denn i wird implizit zu (*)(i*sizeof(*a)) erweitert. Danach werden die beiden Zeiger addiert. Volker
und deshalb kann ich a und i vertauschen?
das ist a ziemlich unwahrscheinlich weil IMHO der pointer auf das array
z.b. mit z.B. 4 multipliziert werden würde und man damit "irgendwo"
ist..
und B
>sizeof(*a)
nachdem i ja "alles mögliche" sein kann (byte/word/int usw.)
wird, wenn man a und i vertauscht aus sizeof(*a) (also sizeof(*i) wird)
ja entweder 1, 2, 4 ...
man multipliziert also entweder mit 1, 2 oder 4
was nicht stimmen kann
würd mich jetzt also WIRKLICH interessieren, was ich da jetzt übersehen
hab..
Gast
#2328255
http://manderc.manderby.com/operators/arrayelementoperator/index.php Vermutlich hat der Compiler intelligent genug zu sein um nachzuhalten welcher Teil des Ausdrucks ein Pointer und welcher ein Integer ist. Bei einer Pointeraddition addiert man ja auch nicht zwei Pointer sondern Pointer und Integer. Auch gut fürs C-Verständnis: Die Aufgabe aus dem K&R, eine Funktion zu schreiben die messen kann wieviel Byte ein Integertyp nun wirklich hat (IIRC nach dem 4. oder 5. Kapitel in der 2. Ausgabe).
>der C Compiler intelligent haha >a[i] und i[a] in C identisch? kann mir das jetzt jemand erklären oder nicht?
Robert L. schrieb: > kann mir das jetzt jemand erklären oder nicht? In C ist -entgegen anderslautender Behauptungen- nicht alles erlaubt. Erlaubt ist beispielsweise int+int, char+int, char+char etc.. Nicht erlaubt ist beispielsweise Zeiger+Zeiger. Dagegen wieder erlaubt ist Zeiger+int ebenso wie int+Zeiger (wegen der Kommutativität der Addition beide Versionen). Dabei ist festgelegt, daß erstens ein Zeiger rauskommt, und zweitens das Ergebnis sich ergibt, indem der int-Operand mit der Größe dessen multipliziert wird, worauf der Zeiger zeigt, erhöht um den Wert des Zeigers. Und das eben unabhängig davon, ob der Zeiger vorne steht oder die int. Damit ist geregelt, was Zeiger+int bewirkt, also ist damit auch klar, was *(Zeiger+int) macht, ebenso wie das gleichwertige *(int+Zeiger). Weiterhin ist eines[anderes] nur eine andere Schreibweise für *(eines+anderes). Also steht zeiger[int] für *(zeiger+int) und int[zeiger] steht für *(int+zeiger). Beides ist nach obiger Regel aber gleichwertig.
hey super habs verstanden wenigstens einer der sich in c auskennt, und nicht nur so tut als ob ;-) >indem der int-Operand mit der Größe >dessen multipliziert wird, worauf der Zeiger zeigt, DAS war das was ich nicht wusste...
Gast
#2391998
Moin. Hab das hier grad mal ein wenig überflogen. Nur nochmal als kleine ergänzung: Das "Zeiger + Zeiger" nicht erlaubt ist, ist so nicht ganz richtig. Es gibt einfach keine praktisch sinnvolle Anwendung, weshalb man 2 Zeiger addieren sollte. Deswegen wurde dies nicht implementiert. und zu der ursprünglichen Frage / dem Ursprünglichen Problem: "," durch "." ersetzen.... Gehe Das Array Zeichen für Zeichen durch und schaue ob das Zeichen ein"," ist. Wenn ja, dann ersetze "," durch ".", wenn nicht, lass das zeichen in ruhe. Ich denke mal, das das Problem schon gelöst ist, trotzdem nochmal standard C-Code dazu: (Dies ist nur ein Beispiel mit einem vordefinierten Array! Der Code ist für ein Win32-Konsolenprojekt ausgelegt!)
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
Grüße Chocco
Gast
#2392757
Klaus Wachtler schrieb: > Dabei ist festgelegt, daß erstens ein Zeiger rauskommt, und zweitens > das Ergebnis sich ergibt, indem der int-Operand mit der Größe > dessen multipliziert wird, worauf der Zeiger zeigt, erhöht um den Wert > des Zeigers. Das ist ja auch mit der Hauptgrund, warum es in C überhaupt Zeigertypen gibt. Chocco schrieb: > Das "Zeiger + Zeiger" nicht erlaubt ist, ist so nicht ganz richtig. Doch, das ist richtig. Es ergibt auch keinen Sinn, weil ein Zeiger immer eine absolute Adresse darstellt. Das ist etwa so, als wolle man den 3.5.2010 und den 24.10.2011 addieren. Man kann Tage zu einem Datum hinzuzählen, dann kommt man bei einem neuen Datum heraus, aber man kann kein anderes Datum dazuaddieren, weil das keinen Sinn ergibt. Man kann aber umgekehrt von einem Datum ein anderes abziehen und bekommt dann eine Differenz in Tagen. Und genau nach dem selben Prinzip verhalten sich auch Zeiger. > Es gibt einfach keine praktisch sinnvolle Anwendung, weshalb man 2 > Zeiger addieren sollte. Deswegen wurde dies nicht implementiert. Ähm, die Konseuqenz aus dieser Aussage wäre dann doch, > Das "Zeiger + Zeiger" nicht erlaubt ist oder?
auch wenn es "nur" ein Beispiel ist, aber DAS macht man nicht: for( i=0 ; i<23 (das 23 mein ich) (IMHO sind in "good old" C auch eher 0 terminierte "Strings" üblich (und keine array) Außerdem leben wird im "Zeitalter" von unicode da ist das Ganze nicht mehr so trivial..
Das Beispiel ist eh ziemlich schrullig. Es sind ja nur 22 Byte Nutzdaten im String, und die abschließende 0. Trotzdem werden 23 Zeichen geprüft. Und wie > standard C-Code und > #include <windows.h> ... > Win32-Konsolenprojekt ... > system("pause"); zusammengehen, weiß ich auch nicht so recht.
Gast
#2393190
Nach der Fehlermeldung die er bekommt ist das kein C Compiler.
Gast
#2394561
Entschuldigt bitte, aber das, was ich da oben an Code gepostet habe wurde MIR, so wie es da steht, als Standard C-Code beigebracht! :( Klärt mich doch bitte auf, wenn dies so nicht der wahrheit entsprechen sollte. Und zu den Zeigern: Meine Aussage war falsch formuliert, und dafür entschuldige ich mich viel mals. Es sollte eigentlich nur eine ergänzung sein, warum Zeiger+Zeiger nicht erlaubt / möglich ist. Entschludigt bitte mein unwissen, ich kann nichts dafür, das in Lehranstalten nur noch die halbe wahrheit erzählt wird. :(
Chocco schrieb: > Entschuldigt bitte, aber das, was ich da oben an Code gepostet habe > wurde MIR, so wie es da steht, als Standard C-Code beigebracht! :( Standard ist im Zweifelsfall, was im K&R oder im entsprechenen ISO-Blatt steht, je nach C-Version. (Es sei denn, man folgt dem, was Microsoft als Standard gern hätte, dann ist das natürlich was anderes.) Dazu gehört schon mal kein windows.h. Weiterhin ist zwar system() eine Standardfunktion, aber was man an system() als Kommando übergeben kann und wie das dann funktioniert, ist schwer vom Betriebssystem bzw. der Umgebung des Programms abhängig. PAUSE geht halt nur unter Windows, auf einem anderen System braucht man auch den ganzen Plunder mit system an der Stelle nicht. Abgesehen davon, daß es mit Kanonen auf Spatzen geschossen ist, wenn man einen Kommandointerpreter startet, den ein Kommando ausführen lässt, was dann wieder auf eine Eingabe wartet, nur um das eigenen Programmende zu verzögern, bis der Benutzer Return tippt. Ein schnödes getchar() würde auf jedem System funktionieren (deklariert in stdio.h auf jedem System). Chocco schrieb: > Entschludigt bitte mein unwissen, ich kann nichts dafür, das in > Lehranstalten nur noch die halbe wahrheit erzählt wird. :( Du kannst nur etwas dafür, wenn du es unreflektiert weiter erzählst :-) Den Rest der Wahrheit muß man immer selbst besorgen...
Gast
#2394855
Danke dir. werd´s mir merken :)
Gast
#2396306
Zur eigentlichen Frage: Was spricht gegen
1 | |
aus der Standard-C-Library?
Gast
#2396452
"strrepl" und "Standard-C-Library" passen nicht zusammen.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.