Gerade/ungerade Zahlen herauslesen



  • Guten Abend!

    Ich hab mir überlegt ein Programm zu schreiben das aus einem Textdokument gerade und ungerade zahlen herausliest?

    Nur leider hab ich keine Schimmer wie das machen soll :D?
    Habt ihr vielleicht ein paar Tipps parat?

    Ginge das net irgendwie mit Modulo?

    Gruß



  • Ohne die Zahl auszulesen, kannst du nicht feststellen, ob sie gerade ist. Deshalb: Alle Zahlen lesen und dann per if(zahl%2==0)...else... entscheiden, was du weiter damit machst.



  • nun ja, im prinzip so:

    datei öffnen
    zeilenweise auslesen
    strings auswerten ("123" in 123 umwandeln (1 != '1' weil 1 in ASCII == Steuerzeichen)
    wenn zahl gerade
        anzahl geradezahlen erhöhen
    ansonsten
        anzahl ungeradezahlen erhöhen
    


  • Kannst auch prüfen, ob das letzte Bit 1 ist oder nicht. Also so:

    if(zahl&1L) //Zahl ist ungerade
    else //Zahl ist gerade
    


  • Jochen S. schrieb:

    Kannst auch prüfen, ob das letzte Bit 1 ist oder nicht. Also so:

    if(zahl&1L) //Zahl ist ungerade
    else //Zahl ist gerade
    

    ehm, wenn er nich mal ne vorprogrammierten versuch zeigt was er probiert hat, ist
    bitmanipulation schon ein wenig zu viel für ihn... aber sonst ne nice idee =b



  • Ok, danke!

    Noch was:
    Wir wie ja alle wissen liest fscanf aus eine Text-Datei und speichert es in eine Variable.

    Wenn ich jetzt in der Text-Datei steht:
    5 6 3
    6 6 8

    Das sind ja 3 Spalten.

    fscanf(file,"%d %d %d",&a,&b,&c);
    In diesen Fall ist a= 5 und/oder 6. Und b die Werte der 2. und c die Werte der 3. Spalte. Dann wird in a die 1. Spalte in b die 2. Spalte und in c die 3. Spalte gespeichert.

    Warum ist das so? (Wenns stimmt was ich da sage?)

    Wenn ich jetzt hingegen das mache(Gleiches Text-Dokument):
    fscanf(file,"%d",&a) dann liest es ja Zahl für Zahl und speichert es halt einzeln in den interger a.

    Sieht euch den Vergleich an. - Warum?

    Jetzt haben wir dieses Textdokument:
    56 689
    30 50

    Und was ist wenn man jetzt die "56" und "689" als ganze Zahl haben will.
    Muss man dann ein String-Array verwenden. ---> z.B. char zahl[100]

    fscanf(file,"%s",&zahl) --> Es werden jetzt die Zahlen "56" "689"(dazwischen natürlich das Leerzeichen) usw. in zahl gespeichert?

    fscanf(file,"%s %s",&zahl1,zahl2) ---> Hier wird dann wieder "56" und "30" in zah1 gespeichert. Also 2. Spalte in zahl1 und 2. Spalte in zahl2?

    Danke 😉



  • Billy schrieb:

    Ok, danke!

    Noch was:
    Wir wie ja alle wissen liest fscanf aus eine Text-Datei und speichert es in eine Variable.

    Wenn ich jetzt in der Text-Datei steht:
    5 6 3
    6 6 8

    Das sind ja 3 Spalten.

    fscanf(file,"%d %d %d",&a,&b,&c);
    In diesen Fall ist a= 5 und/oder 6. Und b die Werte der 2. und c die Werte der 3. Spalte. Dann wird in a die 1. Spalte in b die 2. Spalte und in c die 3. Spalte gespeichert.

    Warum ist das so? (Wenns stimmt was ich da sage?)

    fscanf() liest die Datei zeichenweise von vorne nach hinten, solange es die Inhalte entsprechend dem angegebenen Formatstring deuten kann. Hier stehen im Formatstring drei "%d", also sucht es nach drei Zahlen-Angaben, d.h. nach dem ersten Aufruf ist a=5, b=6 und c=3 und der Lesezeiger der Datei steht am Ende der ersten Zeile. Wenn du nochmal mit dem selben Formatstring einliest, ist a=6, b=6 und c=8, bei einem dritten Durchlauf bekommst du einen Fehler (weil die Datei zu Ende ist).

    Wenn ich jetzt hingegen das mache(Gleiches Text-Dokument):
    fscanf(file,"%d",&a) dann liest es ja Zahl für Zahl und speichert es halt einzeln in den interger a.

    Sieht euch den Vergleich an. - Warum?

    Das selbe Prinzip wie oben, nur daß der Formatstring nur eine Angabe "%d" enthält.

    Ansonsten solltest du dich mal etwas genauer mit der Funktionsweise der scanf()-Familie beschäftigen 😉



  • Ok :D.

    Und wie ists mit %s?

    Was ich da erzählt habe?



  • Mit %s funktioniert es genauso wie mit %d, nur daß die Datei-Inhalte nicht als Zahlen interpretiert werden, sondern als Zeichenketten (und fscanf() liest alles bis zu einem Whitespace).



  • Danke!
    Meinst du das so? Mit den Strings...

    Textdokument:
    56 689
    30 50

    char temp[100]
    fscanf(file,"%s",&temp);

    Hier wird nicht zeichenweise eingelesen oder?
    Kannst du erklären was vom Anfang bis zum Ende einglesen wird?

    Und was passiert wenn ich jetzt: fscanf(file."%s %s",&temp, &temp1) schreibe?

    Bitte, Danke :).



  • Billy schrieb:

    Danke!
    Meinst du das so? Mit den Strings...

    Textdokument:
    56 689
    30 50

    char temp[100]
    fscanf(file,"%s",&temp);

    Hier wird nicht zeichenweise eingelesen oder?
    Kannst du erklären was vom Anfang bis zum Ende einglesen wird?

    Erstmal brauchst du bei char-Arrays nicht noch extra die Adresse zu bilden.
    Und zweitens: Der Grundsatz von fscanf() besteht darin, alle Zeichen zu lesen und zu verarbeiten, die zum Format passen. Zum Format "%d" passen die Ziffern 0 bis 9, zum Format %s alles außer Whitespaces (Leerzeichen, Tab, Newline). Das bedeutet, wenn du den Aufruf in einer Schleife ausführst:
    [cpp]while(!feof(file))
    {
    int ret = fscanf("%s",temp);
    printf("%d: %s\n",ret,temp);
    }[/cpp}erhältst du insgesamt fünf Ausgaben - viermal 1 (ret ist die Anzahl erfolgreich verarbeiteter Format-Kennungen) mit den Zahlen aus deiner Datei und zuletzt -1 (Kennzeichen für Lesefehler, hier verursacht durch das Dateiende) und 50 (die letzte erfolgreich eingelesene Zeichenkette).

    Und was passiert wenn ich jetzt: fscanf(file."%s %s",&temp, &temp1) schreibe?

    Leerzeichen im Formatstring werden afaik ignoriert, Whitespaces vor einer verarbeitbaren Eingabe werden übersprungen. Das heißt, fscanf() liest die Zeichen '5', '6' und ' ' und merkt, daß die erste Eingabe zu Ende ist ("56" wird in temp gespeichert). Weil der FOrmatstring noch weitergeht, liest fscanf() anschließend weiter '6', '8', '9' und '\n' (wieder ein Whitespace - "689" landet in temp2). An der Stelle ist der Formatstring zu Ende und fscanf() gibt 2 an den Aufrufer zurück.



  • Und das \0 wird auch ignoriert?



  • Welches '\0' meinst du denn jetzt? In einer normalen Textdatei kommt eigentlich keins vor (und ich bin mir auch nicht sicher, wie C damit umgehen würde) und in den geschriebenen Strings wird automatisch eins als Stringende-Zeichen angehängt.



  • Ah ok.

    Also jetzt das ganze zusammen gefasst :D:

    In Text-Datei steht:
    2 3 2
    6 6 7

    fscanf(file1,"%d",%zahl) ---> liest 2 dann leerzeichen dann 3 usw. zeichenweise halt^^.

    fscanf(file1,"%d %d %d"&a,&b,&c) ---> es speichert einfach 2 in a 3 in b und 2 in c.

    In Text-Datei steht:
    255 565
    165 10

    Wenn mann hier jetzt also Zahlgruppen speichern will dann muss man Strings-Array verwenden? So ungefähr stimmts?

    char temp[100]

    fscanf(file1,"%s",&temp)---> jetzt liester es 2 dann 5 dann 5 dann ist ein leer ---> es speichert 255 in temp dann geht weiter liest 5 6 dann 5 sieht \n speichert wieder 565 in temp...

    fscanf(file1,"%s %s"&temp, &temp1) ---> jetzt dadurch das jetzt 2 %s hier sind, liest es wie oben nur speichert es halt 255 in temp und 565 in temp1.

    Dürfte eigentlich im Großen und Ganzem stimmen oder?



  • Billy schrieb:

    Ah ok.

    Also jetzt das ganze zusammen gefasst :D:

    In Text-Datei steht:
    2 3 2
    6 6 7

    fscanf(file1,"%d",%zahl) ---> liest 2 dann leerzeichen dann 3 usw. zeichenweise halt^^.

    fscanf(file1,"%d %d %d"&a,&b,&c) ---> es speichert einfach 2 in a 3 in b und 2 in c.

    In Text-Datei steht:
    255 565
    165 10

    Wenn mann hier jetzt also Zahlgruppen speichern will dann muss man Strings-Array verwenden? So ungefähr stimmts?

    Nein, die Datei kannst du auch als Zahlen verarbeiten. Bei %d liest er solange, bis das nächste Zeichen keine Ziffer ist, und fasst das Ergebnis dann zu einem Zahlenwert zusammen.
    Das ist die große Stärke von fscanf() - er läuft zwar intern zeichenweise durch die Datei, aber er kann die gelesenen Zeichen(folgen) auch sinnvoll interpretieren.

    Wenn du mehrere Format-Kennungen in dem String hast, macht er so lange weiter, bis er entweder am Dateiende angekommen ist oder den kompletten Formatstring ausgewertet hat (und schreibt die gelesenenen Werte der Reihe nach in die übergebenen Parameter).

    (Randfrage: Was verwendest du denn als Lernhilfe, abgesehen vom Forum?)



  • Danke.

    So...
    Nun hab ich das ganze mit den ungerade und geraden zahlen programmiert.
    Also es soll aus zahlen.txt alle ungeraden in ungerade.txt und alle geraden Zahlen in gerade.txt speichern.

    zahlen.txt enthält:
    15683256

    Nur kommen 2 Fehler die ich überhaupt nicht kenne(Anfänger 😉 ) und noch nie gehabt habe.

    1>C:\Dokumente und Einstellungen\....\Eigene Dateien\Visual Studio 2008\Projects\file003.c\Debug\file003.c.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise
    
    1>file003.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_foef" in Funktion "_zahlen".
    

    Es kommen auch Warnungen das fopen und fscanf möglicherweise unsafe sind.
    Ich glaub die sind aber nicht von großer Bedeutunng?

    Hier das Programm:

    #include <stdio.h>
    #include <stdlib.h>
    
    void zahlen(char filename[]);
    
    void zahlen(char filename[])
    {
      FILE*file1=NULL;
      FILE*file2=NULL;
      FILE*file3=NULL;
    
      int c=0;
    
      file1=fopen(filename,"r");
      if(file1==NULL)
      {
        printf("fehler beim lesen");
    	exit(-1);
      }
    
      file2=fopen("gerade.txt","w");
      if(file1==NULL)
      {
        printf("fehler beim schreiben");
    	exit(-1);
      }
      file3=fopen("ungerade.txt","w");
      if(file3==NULL)
      {
        printf("fehler beim schreiben");
    	exit(-1);
      }
    
      while(!foef(file1))
      {
        fscanf(file1,"%1d",&c);
    
    	if(c%2 == 0)
    	{
    	  fprintf(file2,"%d",c);
    	}
    	else
    	{
    	  fprintf(file3,"%d",c);
        }  
      }
    
      fclose(file1);
      fclose(file2);
      fclose(file3);
    }
    
    int main()
    {
      char filename[50]="zahlen.txt";
    
      zahlen(filename);
    
      return(0);
    }
    


  • Billy schrieb:

    Nur kommen 2 Fehler die ich überhaupt nicht kenne(Anfänger 😉 ) und noch nie gehabt habe.

    1>C:\Dokumente und Einstellungen\....\Eigene Dateien\Visual Studio 2008\Projects\file003.c\Debug\file003.c.exe : fatal error LNK1120: 1 nicht aufgelöste externe Verweise
    
    1>file003.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_foef" in Funktion "_zahlen".
    

    So etwas nennt sich Buchstabendreher 😉
    Obwohl, eigentlich hätte der Compiler dich auch schon auf die undefinierte bzw. implizit deklarierte Funktion hinweisen sollen.

    PS: Ist das richtig, daß in der Datei nur eine einzige Zahl steht? Wenn nein, was genau erwartest du als Ergebnis? (Edit: hat sich erledigt)

    PPS: Nur ein Vorschlag - verwende bitte Variablennamen, die auch ein wenig Informationsgehalt haben. "eingabe", "gerade" und "ungerade" sind wesentlich aussagekräftiger als "file1", "file2" und "file3".



  • So etwas nennt sich Buchstabendreher 😉
    Obwohl, eigentlich hätte der Compiler dich auch schon auf die undefinierte bzw. implizit deklarierte Funktion hinweisen sollen.

    PS: Ist das richtig, daß in der Datei nur eine einzige Zahl steht? Wenn nein, was genau erwartest du als Ergebnis?

    Naja, ich das hab ich mir so gedacht:
    Ich hab ein Textdokument vorgegeben. Nämlich zahlen.txt --> hier steht drinnen:
    56851526

    mit fscanf(zahlen,"%1d",c);---> leist ja 5 speichert es in c ---> liest dann 6 speichert es in c usw.

    Die if überprüft halt ob es eien gerade oder eine ungerade Zahl ist.
    Gerade zahlen werden in gerade.txt gespeichert und ungerade Zahlen in ungerade.txt



  • Billy schrieb:

    So etwas nennt sich Buchstabendreher 😉
    Obwohl, eigentlich hätte der Compiler dich auch schon auf die undefinierte bzw. implizit deklarierte Funktion hinweisen sollen.

    PS: Ist das richtig, daß in der Datei nur eine einzige Zahl steht? Wenn nein, was genau erwartest du als Ergebnis?

    Naja, ich das hab ich mir so gedacht:
    Ich hab ein Textdokument vorgegeben. Nämlich zahlen.txt --> hier steht drinnen:
    56851526

    mit fscanf(zahlen,"%1d",c);---> leist ja 5 speichert es in c ---> liest dann 6 speichert es in c usw.

    OK, ich nehme mein PS von oben zurück - ich hatte 1 dort oben übersehen.



  • Sorry, aber was soll ich jetzt machen :)?


Anmelden zum Antworten