Dateiverarbeitung



  • robc++ schrieb:

    Eine Umwandlung brauch ich aber nicht von den Buchstaben oder?

    'A' == 65. Das ist schon so, dafür brauchst du nichts umwandeln.


  • Mod

    robc++ schrieb:

    Also das Programm weiß das die ASCII Tabelle benutzt wird (also die Zahlen).

    Nein, nicht wirklich. Aber Zeichen sind immer Zahlen, du kannst immer damit rechnen und das soll hier gelernt werden. Ist die benutzte Zeichentabelle (dies wird von der Umgebung festgelegt, nicht von deinem Programm!) ASCII-artig, dann klappt das mit dem Trick, 'A' vom Buchstaben abzuziehen, um den Index zu bekommen, denn bei ASCII und Nachfolgern sind alle lateinischen Buchstaben hintereinander. Du darfst davon ausgehen, auf allen gängigen Systemen einen solchen Zeichensatz zu finden. Unschön ist halt, dass es nicht auf jedem denkbaren System läuft und nur mit lateinischen Buchstaben. Allgemein wäre daher die genannte map besser, aber das soll hier nicht gelernt werden und kommt sicherlich (viel) später im Kurs, wenn komplexe Datenstrukturen besprochen werden.



  • Swordfish schrieb:

    robc++ schrieb:

    Eine Umwandlung brauch ich aber nicht von den Buchstaben oder?

    'A' == 65. Das ist schon so, dafür brauchst du nichts umwandeln.

    Das ist nicht so wichtig. Wichtig ist, dass gilt:

    'B' == 'A' + 1
    'C' == 'A' + 2
    

    usw.



  • Also so sieht das bisherige Programm aus:

    #include<iostream>
    #include<fstream>
    #include<string>
    #include<cstdlib>
    using namespace std;

    int main ()
    {
    string quellname;
    ifstream Datei;
    char Zeichen;
    int index;

    cout<<" Bitte Quellname eingeben"<<endl;
    cin>> quellname;

    Datei.open(quellname.c_str());

    if (!Datei)
    {
    cerr<<" Kann nicht geöffnet werden"<<endl;
    exit (-1)
    }

    int zaehlerfed[26];

    while (Datei.get(zeichen))
    {
    if (zeichen>='A'&&zeichen<='Z')
    {

    }

    Was genau muss den jetzt gemacht werden ich muss doch jetzt prüfen ob welcher Buchstabe das ist und dann den Zaehler erhöhen odeR?

    if (zeichen>='A'&&zeichen<='Z')
    {
    index=zeichen-'A';
    if(zeichen=='A')
    [
    zaehlerfeld[1]++; /geht das???
    ]
    if (zeichen=='B')
    [
    zaehlerfeld[2]++
    ]

    ....



  • Sorry das Programm müsste ja dann so aussehen :

    if (zeichen>='A'&&zeichen<='Z')
    {
    index=zeichen-'A';

    if(index==0)
    [
    zaehlerfeld[1]++; /geht das???
    ]
    if (index==2)
    [
    zaehlerfeld[2]++;
    ]

    if(index==3)
    {
    zahlerfeld [3]++;
    }



  • Belli schrieb:

    ...

    Nun hast Du in index 0 wenn Dein Zeichen 'A' war, und 25, wenn Dein Zeichen 'Z' war, oder halt irgendwas dazwischen. Mit diesem Index kannst Du jetzt auf Dein Feld zugreifen und den entsprechenden Wert inkrementieren.



  • Ich gebe dir mal eine Musterlösung, dann kannst du [c]vergleichen[/c].

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main()
    {
    	ifstream file("daten.txt");
    	unsigned capitals[26] = {};
    
    	for(char c; file>>c;)
    	{
    		if( c>='A' && c<='Z' )
    			++capitals[c-'A'];
    	}
    
    	for(char c='A'; c<='Z'; ++c)
    		cout << c << ": " << capitals[c-'A'] << endl;
    }
    


  • unsigned capitals[26] = {};

    Wieso unsigned?

    for(char c; file>>c;)
    {
    if( c>='A' && c<='Z' )
    ++capitals[c-'A'];
    }

    for(char c='A'; c<='Z'; ++c)
    cout << c << ": " << capitals[c-'A'] << endl;
    }
    Kannst du den Abschnitt kurz erklären?



  • Cool Danke, ich glaub ich habs verstanden

    capital[c-'A']

    wenn es A ist dann -> 65-65 --> speichert in Feld [0]

    das is ja echt schon die Lösung.

    Vielen Dank



  • unsigned, weil ein Zähler ja nicht kleiner als 0 werden kann. Ein Buchstabe kann ja nicht weniger oft als 0x vorkommen.

    Du hast ein Array von 26 Elementen. Der Zugriff erfolgt dann über die Indizes 0 bis 25. 'A' hat irgendeinen Wert. 'A'-'A'=0, 'B'-'A'=1 .... 'Z'-'A'=25 Du siehst also, die Indizes passen genau, von 0 bis 25. Das ++ erhöht einfach den Zähler des entsprechenden Buchstabens. Die if erklärt sich ja von selbst (nur Großbuchstaben zählen) und das am Ende ist einfach nur eine Testausgabe.

    Eine for Schleife besteht aus 3 Teilen:
    1. Laufvariable
    2. Bedingung
    3. Irgendwas, das immer nach einem Schleifendurchlauf passieren soll.
    --> file>>c ließt genau 1 Zeichen aus der Datei und speicher das Zeichen in der Laufvariable c. Der Rückgabewert dieser Operation ist einfach gesagt true, wenn sie erfolgreich war, ansonsten false.



  • Vielen Dank für die Informationen.

    Kann ich den meine vorgehensweise auch anwenden also mit dem
    Datei.open(quellname.c_str())
    und die Prüfung ob die Datei geöffnet werden kann?

    Wie bist du den so schnell auf die Lösung gekommen?
    wie ist deine vorgehensweise bei c++?



  • Ich werf' mal <cctype> in die Suppe ...

    out schrieb:

    [...]
    

    =>

    #include <iostream>
    #include <fstream>
    #include <cctype>
    
    using namespace std;
    
    int main()
    {
    	ifstream file("daten.txt");
    	unsigned counter[ 'Z' - 'A' ] = {};
    	int ch = 0;
    
    	while( ch = file.get(), file.good() ) {
    
    		if( isalpha( ch ) ) {
    
    			++counter[ toupper( ch ) - 'A' ];
    		}
    	}
    }
    


  • #include<iostream>
    #include<fstream>
    #include<string>
    #include<cstdlib>
    using namespace std;

    int main ()
    {
    string quellname;
    ifstream Datei;
    char Zeichen;
    unsigned Feld[26]= {};

    cout<<" Bitte Quellname eingeben"<<endl;
    cin>> quellname;

    Datei.open(quellname.c_str());

    if (!Datei)
    {
    cerr<<" Kann nicht geöffnet werden"<<endl;
    exit (-1)
    }

    while (Datei.get(zeichen))
    {

    if (zeichen>='A'&&zeichen<='Z')
    {
    ++Feld[zeichen-'A'];
    }

    for(char=zeichen='A'; zeichen<='Z'; ++zeichen)
    {
    cout<<zeichen<<":"<<Feld[zeichen-'A']<< endl;
    }
    }
    }

    Ist der Quellcode so ok? oder habe ich noch fehler???

    wofür dient eig : system("dir");????????????

    Wie kann ich laut meinen Quellcode eig diete abfrage nach der quelldatei umgehen?

    kann ich daten.txt so einbinden? ich mein der benutzer muss das ja eingeben.

    DAnke



  • Swordfish schrieb:

    ...
    	while( ch = file.get(), file.good() ) {
    	
    		if( isalpha( ch ) ) {
    		
    			++counter[ toupper( ch ) - 'A' ];
    		}
    	}
    }
    

    Vielleicht solltest Du Dir die Aufgabenstellung genauer ansehen ...



  • Belli schrieb:

    Vielleicht solltest Du Dir die Aufgabenstellung genauer ansehen ...

    Hoppala 🤡

    while( ch = file.get(), file.good() ) {
    
    	if( isupper( ch ) ) {
    
    		++counter[ ch - 'A' ];
    	}
    }
    

    Belli schrieb:

    Swordfish schrieb:

    robc++ schrieb:

    Eine Umwandlung brauch ich aber nicht von den Buchstaben oder?

    'A' == 65. Das ist schon so, dafür brauchst du nichts umwandeln.

    Das ist nicht so wichtig. [...]

    Ich wollt nur klarstellen, daß ein "Buchstabe" eine Zahl ist.

    Mensch, Du hast mich aber heute am Kieker ... 😉

    // edit: tagsoup detected.



  • robc++ schrieb:

    Kann ich den meine vorgehensweise auch anwenden also mit dem
    Datei.open(quellname.c_str())
    und die Prüfung ob die Datei geöffnet werden kann?

    Natürlich, solltest du auch. Für das eigentliche Problem habe ich es einfach mal weggelassen.

    robc++ schrieb:

    Wie bist du den so schnell auf die Lösung gekommen?
    wie ist deine vorgehensweise bei c++?

    Hmm, keine Ahnung, ich bin auch nur ein Anfänger hab auch erst 1. c++-Buch gelesen, aber ich habe halt auch schon viele andere Dinge gemacht, im Bereich Informatik. Dann hats so eine Aufgabe eben sofort... Das kommt einfach mit den Jahren. 😃

    Ob die Semantik des Quellcodes stimmt, siehst du, wenn das herauskommt, was du wolltest. Die Prüfung der Syntax nimmt dir ja schon der Compiler ab.


Anmelden zum Antworten