Dateiverarbeitung
-
Robc++ schrieb:
Es müsste ja ein int Feld [24] deklariert werden.
Au, weia.
Wikipedia schrieb:
Das moderne lateinische Alphabet enthält 26 Zeichen.
Konvertieren Sie einen im Text gefundenen Großbuchstaben stets
so, dass das Konvertierungsergebnis direkt als Index für den Zugriff auf den passenden Zähler verwendet werden kann.Du sollst hier eine Eigenschaft der ASCII-Zeichencodierung benutzen und die Tatsache, dass Zeichen auch nur Zahlen sind. Es ist nämlich
'A' + 1 == 'B'(beachte, dass die 1 hier die Zahl, nicht die Ziffer ist'A' + '1'wäre ganz was anderes), … ,'A' + 25 == 'Z'. Entsprechend ist'A' - 'A' == 0und'Z' - 'A' == 25. Der Rest sollte klar sein.Das Problem an der Aufgabe ist streng genommen, dass man ASCII nicht voraussetzen darf. Es gibt tatsächlich reale Systeme, auf denen die obige Annahme nicht gilt. Aber damit will ich dich jetzt nicht verwirren, in 99.9999% aller Fälle ist das so richtig. Die Aufgabenstellung verlangt jedenfalls, dass du es so machst. Wenn du Spaß hast, kannst du ja mal überlegen, wie man es machen könnte, wenn die Großbuchstaben im unterliegenden Zeichensatz nicht mehr hintereinander stehen, ohne dass man 26 if/switch benutzt (Das ist aber ein bisschen schwierig).
-
Ok dann muss ich also ein 26 Feld erstellen und dann jeweils prüfen
..
if( 'A'+1==B)
{
counterb++;
}
if ('A'+2= C)
{
counterc++;
}
...Könnte man auch ein counter [größe] erstellen damit ich nachher bei der Ausgabe eine forschleife benutzen kann?
also würde dann bei einer if Schleife statt counterb++ Counter[1]++Gibt es die möglichkeit die 26 if schleifen zu umgehen?
Hinweis: Bin totaler Anfänger in c++
-
Wenn Du ein Zeichen hast, ermittelst Du erst einmal, ob Du es zählen musst:
if(zeichen >= 'A' && zeichen <= 'Z')Wenn das zutrifft, subtrahierst Du:
index = zeichen - 'A';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.
So hast Du am Ende inFeld[0]die Anzahl der gefundenen 'A's usw.
-
Eine Umwandlung brauch ich aber nicht von den Buchstaben oder?
Also das Programm weiß das die ASCII Tabelle benutzt wird (also die Zahlen).
-
robc++ schrieb:
Eine Umwandlung brauch ich aber nicht von den Buchstaben oder?
'A' == 65. Das ist schon so, dafür brauchst du nichts umwandeln.
-
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' + 2usw.
-
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.