c# im dritten Anlauf



  • Bei dem Versuch, ein Ansi-C-Programm von der Konsole zu portieren auf eine Windows-Anwendung, bin ich zunächst bei C# gelandet. Da ging gar nix. Weil die Philosophie von C# völlig anders ist als C.

    Daraufhin bin ich zu Visual C++ gewechselt, und erstmal ging alles ganz einfach. Man konnte die Code-Blöcke fast 1:1 übernehmen.

    Soweit dachte ich, das Problem ist gelöst. Es kam aber zu einem Haufen von Problemen.

    Beim Kompilieren ergeben sich, wie hier schon richtig geschrieben wurde, Probleme mit den Deklarationen aus den h-Dateien (Zyklische Referenz). Daneben gibt es ungeahnte Probleme mit der Verwendung von Strings. Es gibt praktisch 3 Arten von Strings, nämlich C++, C (array of char) und Systemstrings (Ansi). Das führt zu einem Haufen von Fehlermeldungen und Unverträglichkeiten. Wie man erkennt, wenn man strings den List- oder Textboxen zuordnen will. Das klappt nicht. Oder nur mit einer TypUmwandlung in system.string. Umständlich.

    Es gibt bei Visual c++ kein Intellisense.
    Es gibt bei der Suche im Internet fast keine Codebeispiele in c++, sondern fast nur in C#
    Das intellisense ist ein sehr mächtiges Werkzeug, was bei der Portierung ungemein hilft.

    Nur als Beispiel, Strings: in C# gibt es anders als in C++ gar keine Probleme mit der Typverträglichkeit der Strings.

    Der textBox oder listBox lassen sich strings als string zuordnen, mit der Eigenschaft .ToString() Das geht in C++ garnicht. Umgekehrt gibt es auch keine Probleme dank der Klasse Convert.

    Man muß allerdings seine ganze C-Programmierung schrotten, nichts von der C-Programmierung überlebt das.

    Was mich dazu gebracht hat, war ein Überdenken des Beitrags des hiesigen Moderators Kulmbach, daß sich C++ und Cli nicht vertragen.

    Guter Beitrag. Jedes Wort darin ist wahr.

    Daraufhin hab ich heute in C# die Knackpunkte meiner AnsiC-Programmierung daraufhin getestet, ob es auch in C# laufen könnte.

    Ergebnis: Im dritten Anlauf hab ich C# wie ich meine zumindest soweit verstanden, daß ich meine Applikationen dort umsetzen kann. Und zwar, muß man sagen, ziemlich schnell einfach und ohne Probleme. Alles läuft. Man muß nur umdenken. 1:1 geht gar nicht.

    Es heißt neu strukturieren. Fast nichts vom Ansi-C Code überlebt das. Aber es geht.

    Pascal



  • Liegen ja auch so ungefähr 40 Jahre dazwischen.



  • @pascal2009
    Bitte schreib nicht über Dinge die du nicht verstehst.



  • hustbaer schrieb:

    Bitte schreib nicht über Dinge die du nicht verstehst.

    Nee, ich schreibe von Dingen, die ich versuche.

    Da mir die Philosophie von C# im Anfang völlig rätselhaft war, freue ich mich einfach, daß ich meine Applikationen nunmehr genauso umsetzen kann wie gewollt.

    Der Knoten ist mit einem Male geplatzt.

    Ich kann es in C# so umsetzen, wie ich denke. Es läuft.

    Allerdings: meinen Ansi-C Code muß ich schrotten.

    Pascal



  • So Sätze wie

    Es gibt praktisch 3 Arten von Strings, nämlich C++, C (array of char) und Systemstrings (Ansi). Das führt zu einem Haufen von Fehlermeldungen und Unverträglichkeiten.

    sind einfach nur Quatsch.

    Und das

    Wie man erkennt, wenn man strings den List- oder Textboxen zuordnen will. Das klappt nicht. Oder nur mit einer TypUmwandlung in system.string. Umständlich.

    ist in C# auch nicht anders.

    Dann unterschlägst du dass du mit "Visual C++" ein C++/CLI Projekt meinst. Das kommt dann erst im weiteren Beitrag raus, wenn man etwas zwischen den Zeilen liest.

    Programmier' ruhig weiter, das will ich dir ja nicht vermiesen. Aber schreib bitte keine "ich kenn mich aus und erzähl euch jetzt mal was" Beiträge. Weil du dich eben (noch) nicht auskennst.



  • hustbaer schrieb:

    Weil du dich eben nicht auskennst.

    Das wär ja auch ein Wunder, sich nach einigen Tagen auszukennen.

    Mittleweile bin ich aber von C# ziemlich angetan, weil die Umsetzung meiner Programmiervorgaben damit (nach einigen Problemen im Kopf, Knoten geplatzt) jetzt wunderbar funktioniert.

    Die Vorgabe ist, ein funktionierendes Programm in Ansi-C auf eine Windows-Oberfläche zu übertragen. Statt Konsolensteuerung Maus.

    Z. B. hier, listBox aus einer Datei füllen, Datei enthält mehr als 100 Datensätze. Es geht aber auch mit 2000 Datensätzen, weil die listBox zur Laufzeit dynamisch verwaltet wird (was man in Ansi-C ziemlich von Hand erledigen müßte mit Malloc etc.):

    public Form2()
            {
    
                InitializeComponent();
                Class1 handle = new Class1();
                string buffer = "";
                string fname = handle.dn_kontenrahmen;
                if (!File.Exists(fname))
                {
                    MessageBox.Show("Fehlende Datei:    " + fname); return; 
                }
    
                FileStream _filestream = new FileStream(fname, FileMode.Open, FileAccess.Read);
                StreamReader _streamreader = new StreamReader(_filestream);
    
                while ((buffer = _streamreader.ReadLine()) != null)
                {
                    listBox1.Items.Add(buffer);  
                }
                _streamreader.Close();
                _filestream.Close();
           }
    

    Einfacher gehts doch gar nicht.

    So geht es in C++ überhaupt nicht. Da haben wir Probleme mit den Strings. Statt der Schleife kann man ja auch noch kürzer programmieren. Das ist aber von der Performance her ziemlich wurst. Allmählich kann ich mich für C# erwärmen.

    Und ja, wenn man anfängt, versteht man es noch nicht. Ich sage aber immer: man muß soviel verstehen, wie man es zur Umsetzung seiner Anforderungen benötigt. Nicht soviel wie möglich, sondern soviel wie nötig.

    Pascal



  • Es ist schon toll, wie einfach das funktioniert. In Ansi-C hab ich immer mit dynamischen Listen zu tun, hier zwar auch, aber das erledigt die Laufzeitumgebung, man muß sich nicht drum kümmern.

    Mit diesem Code

    private void listBox1_DoubleClick(object sender, EventArgs e)
            {
                textBox1.Text = listBox1.Items[listBox1.SelectedIndex].ToString();
    
            }
    
            private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                textBox1.Text = "";
            }
    

    hebelt man IndexChangend aus zugunsten von DoubleClick (Funktion mit der Hand eingetragen), was man in den Eigenschaften von listBox allerdings aktivieren muß.

    Es geschieht nun folgendes:

    Sucht der Anwender in der Liste herum, zeigt die Textbox gar nix an (bzw. löscht den alten Eintrag).

    Macht er einen Doppelklick in der Listbox,. erscheint die Auswahl in der Textbox, die man in der Programmierung als string weiterverarbeiten kann.

    Und das mit zwei Zeilen programmiert.

    Klasse!

    Pascal



  • Der große Fortschritt der GUI ist die Kommunikation mit dem Anwender.

    Weil es mit der Maus stattfindet (und weil die Leute das so gewohnt sind, bzw, Akzeptanz eben).

    Zwar kann man in Ansi C die Konsole so programmieren, daß der Anwender sich wahlfrei (und eben nicht sequentiell) durch die Eingabefelder bewegt, aber man hat eben nicht die GUI und nicht die Maus zur Verfügung. Es ist alles Tastatur.

    Eine Maske mit der Tastatur, mit Steuertasten etc. zu bedienen ist zwar von vornherein nicht uneffektiver, als das mit der Maus zu machen, die Akzeptanz ist aber nicht vorhanden.

    Bei der Frage, wie stelle ich Konsole auf Windows um, hab ich nun die Knackpunkte meiner Programmierung ausgetestet. Das sind dynamische Listen, Stringumwandlung von Zahlenformat zu String und umgekehrt, die Verwaltung von globalen Variablen (die es in C# so nicht gibt, aber man kann sie als Konstanten einer Klasse ablegen), Dateiverwaltung und so weiter.

    Das Ergebnis ist, in C# wird das voraussichtlich problemlos laufen, in C++ nicht, da bin ich auf zahlreiche Probleme gestoßen, angefangen mit den zyklischen Referenzen der H-Dateien, die man mit static zwar entschärfen könnte, aber das ist Kosmetik, jedes Problem mit einer Ausklammerung zunächst zu vermeiden. Das ist keine Programmierung.

    Der Preis für die Portierung ist, die ursprüngliche Programmierung in AnsiC zu schrotten.

    Pascal



  • Vor kurzem hast du noch mit aller Kraft gegen C# gewettert (siehe der alte Thread, ist leider gelöscht und nur noch im Googlecache) und jetzt ist plötzlich C# super toll ? 😕
    Woher kommt der plötzliche Umsturz ? 🙄

    Darum die obligatorische Frage: Was willst du mit dem Thread erreichen ?
    Fall du damit wirklich nur sagen willst wie toll du C# findest, kann ich das auch nicht ernst nehmen nach deinen letzten Anti-C#-Flamethreads...

    Naja, zu deinem Code:

    InitializeComponent();
    Class1 handle = new Class1();
    string buffer = "";
    string fname = handle.dn_kontenrahmen;
    if (!File.Exists(fname))
    {
        MessageBox.Show("Fehlende Datei:    " + fname);
        return;
    }
    
    string[] lines = File.ReadAllLines(fname);
    foreach(string line in lines)
    {
        listBox1.Items.Add(buffer);
    }
    

    Ist etwas eleganter so. 😉



  • DarkShadow44 schrieb:

    Vor kurzem hast du noch mit aller Kraft gegen C# gewettert (siehe der alte Thread, ist leider gelöscht und nur noch im Googlecache) und jetzt ist plötzlich C# super toll ? 😕
    Woher kommt der plötzliche Umsturz ? 🙄

    Darum die obligatorische Frage: Was willst du mit dem Thread erreichen ?
    Fall du damit wirklich nur sagen willst wie toll du C# findest, kann ich das auch nicht ernst nehmen nach deinen letzten Anti-C#-Flamethreads...

    Ist etwas eleganter so. 😉

    Ziel ist eine laufende AnsiC-Programmierung auf auf eine Windows-Anwendung zu portieren (GUI).

    Der Umsturz kommt, weil es mir wie Schuppen von den Augen gefallen ist.

    Ich hatte mich mit Visual C++ versucht und festgestellt, daß da jede Menge Probleme aufgetreten sind.

    Dann habe ich den Code VERSUCHSHALBER in C# übertragen unter dem Dateinamen LetzterVersuchMitCSharp und festgestellt, es läuft plötzlich.

    Das war der Knoten im Kopf, der geplatzt ist. Plötzlich konnte ich den Code so setzen, daß der Compiler das verstanden hat. Fast von jetzt auf gleich. So gesehen hat der Versuch mit C++ geholfen, weil man sieht, daß man die Schwierigkeiten in C# gar nicht hat und auch plötzlich der Intellisense wieder arbeitet, den sie in C++ ausgeschaltet haben. Es war plötzlich alles ganz einfach, was vorher schwierig war. Schwer zu erklären warum.

    Foreach -> C# hat viele mächtige Werkzeuge. Ist schon toll. Schleife ist aber auch nicht schlechter, vor allem nicht schlechter lesbar.

    Jedenfalls, mit C# hab ich jetzt alle meine Programmanforderungen in Testprogrammen ausgetestet und es geht.

    Es funktioniert mittlerweile alles wunderbar. Warum das nicht gleich klar war, weiß ich nicht. Ich kann es mir im nachhinein nicht erklären 🤡 Alles, was ich gewollt hatte, geht plötzlich.

    Pascal



  • In C# hab ich die Antwort auf ein Problem gefunden, was so in AnsiC nicht lösbar wäre, nämlich die Länge von Textfeldern durch Variablen/Konstanten festzulegen.

    Das Problem tritt auf, wenn man struct mit gemischen Datentypen int, double, char in Text verwandelt und wieder zurückverwandeln will. Dann ist es wichtig, die Feldlänge zu kennen.

    Wir haben in AnsiC die Möglichkeit, mit #define Präprozessoranweisungen zu geben, z.B.

    #define DOUBLELEN 12

    double BETRAG_STRING[DOUBLELEN}="";

    Wenn man die String-Länge aller Doubles auf 14 erhöhen will, geht das in Ansi-C mit der Änderung von #define, und die Änderung geht durch das ganze Programm durch.

    Aber:

    Angepaßt werden muß auch die weitere Verarbeitung, und wenn die mit sprintf() stattfindet, können die dort eingesetzten Feldlängenbegrenzer nicht mit Variablen oder #define ersetzt werden.

    denn:

    sprintf(buffer,"%12.2f ...

    Die 12.2 ist durch nichts zu ersetzen.

    Das muß alles händisch angepaßt werden und ist eine sehr kritische Fehlerquelle bei Änderungen am Programm, vor allem, was vorhandene Dateien betrifft, weil bei der Rückumwandlung mit falschen Feldlängen natürlich nur Unsinn dabei herauskommt.

    Jetzt habe ich entdeckt, daß in C# die Lösung ganz einfach ist.

    Man deklariert eine Klasse, als Ersatz für die struct in AnsiC, und legt die Feldlänge fest. Also z. B. für

    class Konto

    {

    int kontonr;
    int kontonr_LEN;

    ... und so weiter

    Initialisiert diese mit kontonr_LEN=6; // nicht die Kontonummer, sondern die Stringlänge

    Damit wird für jeden Feldbezeichner mit _LEN die Stringlänge festgelegt, die er bei der Umwandlung und Rückumwandlung in string haben soll.

    Jetzt kann man je nachdem rechts- oder linksbündig umwandeln mit

    Konto k = new Konto(); // der Handle auf die Klasse
    teilstring=k.kontonr.ToString();
    teilstring=teilstring.PadLeft(k.kontonr_LEN);

    Der Witz ist, daß wir hier die in der Klasse festgelegten Feldlängen verwenden. Das ist mit sprintf() nicht möglich, aber in C# geht es. Wir haben die Konto-Nr. mit einer festen Feldlänge als String. Damit kann man den gemischten Datensatz von int, double, string etc. in einen String verwandeln und aus der Textdatei wieder zurücklesen und wieder in gemischte Datentypen zurückverwandeln. In C# bietet sich dafür die Klasse Convert. an.

    Also, ich entdecke fortlaufend sehr schöne Dinge in C#.

    Pascal



  • pascal2009 schrieb:

    sprintf(buffer,"%12.2f ...

    Die 12.2 ist durch nichts zu ersetzen.

    Doch: sprintf(buffer, "%*.*f", 12, 2, ...);



  • Bashar schrieb:

    pascal2009 schrieb:

    sprintf(buffer,"%12.2f ...

    Die 12.2 ist durch nichts zu ersetzen.

    Doch: sprintf(buffer, "%*.*f", 12, 2, ...);

    Die Frage ist, ob man die 12 durch eine Variable ersetzen kann. Nach meinem Kenntnisstand geht das nicht. Man kann nicht für die 12 ein "x" einsetzen. Oder irre ich?

    Pascal



  • Das sollte doch jetzt offensichtlich sein 😕

    int x = 12;
    sprintf(buffer, "%*.2f", x, ...);
    


  • Bashar schrieb:

    Das sollte doch jetzt offensichtlich sein 😕

    int x = 12;
    sprintf(buffer, "%*.2f", x, ...);
    

    C++ oder Ansi-C??? In Ansi kann ich mit dem Platzhalter * nichts anfangen. Den kenne ich gar nicht.

    Pascal



  • C natürlich, C++ hat mit printf nichts am Hut.

    In Ansi kann ich mit dem Platzhalter * nichts anfangen.

    Aber dein Compiler.

    Den kenne ich gar nicht.

    Klar, sonst hätte ich dir von ihm ja nicht erzählen müssen.



  • Bashar schrieb:

    C natürlich, C++ hat mit printf nichts am Hut.

    In Ansi kann ich mit dem Platzhalter * nichts anfangen.

    Aber dein Compiler.

    Den kenne ich gar nicht.

    Klar, sonst hätte ich dir von ihm ja nicht erzählen müssen.

    Wenn das so gehen würde, Kasten Bier franco wär ja das mindeste.

    Denn speziell darüber würde ich mich sehr freuen, wenn es geht.

    Werd das morgen ausprobieren, heute zu müde.

    Pascal

    PS: Wenn DAS funktioniert, kann ich nur sagen: echt cool, daß du solche Sachen weißt. Da wär ich im Traum nicht drauf gekommen.



  • pascal2009 schrieb:

    PS: Wenn DAS funktioniert, kann ich nur sagen: echt cool, daß du solche Sachen weißt. Da wär ich im Traum nicht drauf gekommen.

    Und das ist das Kernproblem Deiner ganzen Bemühungen. Bei Lernen einer Sprache oder Bibliothek geht es selten darum, auf etwas zu "kommen". Man kann das alles nachlesen und systematisch lernen.



  • Nix für ungut, aber du tust es dir und uns extrem schwer. Trenne zunächst GUI-Dinge und interne Berechnungen.
    Vergiss alle durch Bibliotheken verbesserte Ansätze wie printf und co. Gilt sowohl für C# als auch C++

    Mache dich vertraut mit dem Konzepten von .NET / C# - vor allem mit den Begriffen Eigenschaften (properties),
    Methoden (Funktionen) und Ereignissen (events). Der Einstieg ist nicht besonders schwer. Ein völliger
    Neueinsteiger hat es da deutlich leichter, weil er frei im Kopf ist.



  • @bashar

    Das mit dem * funktioniert 1A. Danke!

    @my @bernie

    Ich hab mir jetzt statt learning by doing doch tatsächlich ein Buch gekauft. Frischalowski Visual C# Einstieg für Anspruchsvolle. Bin jetzt bei Seite 98 angekommen.

    Das Problem ist wohl weniger der Code als die Denke. Von prozedural zu OOP. OOP hab ich ehrlich gesagt bisher nicht verstanden. Vielleicht ändert sich das ja. 😉

    In der .NET Bibliothek finden sich ganz feine Sachen wie ArrayList. Mit Sort-Algorithmus. Das sind alles dynamische Strukturen, die in AnsiC natürlich auch möglich sind, aber einen ziemlichen Aufwand erfordern und außerdem beim kleinsten Fehler den Speicher abschießen. In AnsiC muß man eben alles zu Fuß machen, in C# .NET gibt es die Bibliotheksfunktionen. Solche Dinge sind mit C# schon gut gelöst, muß man zugeben.

    Pascal


Anmelden zum Antworten