Textfilter per Konsole...finde den Fehler nicht :(



  • Hallo Zusammen...

    Ich möchte (muss :-\) einen Textfilter schreiben der einen string nach ent. vorgaben auswertet. Zum besseren Verständnis paste ich mal kurz die Aufgabenstellung:

    Schreiben Sie einen Filter, der eine Zeichenkette (Textdatei)
    über stdin einliest und diese je nach KommandozeilenParameter
    unterschiedlich verarbeitet. Die Verarbeitung soll dabei
    zeichenweise erfolgen (getchar() und putchar()).
    • Wird kein Parameter angegeben, so bleiben die Daten
    unverändert und werden direkt auf stdout ausgegeben.
    • Wird der Parameter u angegeben, so sollen nur alle
    Großbuchstaben ausgegeben werden.
    • Wird der Parameter l angegeben, so sollen nur alle
    Kleinbuchstaben ausgegeben werden.
    • Ist zusätzlich zu u oder l noch der Parameter c angegeben
    worden, so sollen alle Buchstaben in das entsprechende Format
    konvertiert werden (Groß/Kleinschreibung).

    Sobald ich das programm ausführe bekomme ich speicherfehler en mase,
    das liegt wohl an der Art und weise wie ich versuche auf argv zuzugreifen...aber ich frimmel schon den halben Tag daran rum und es bessert sich nichts 😞 vielleicht könnt ihr mir ja helfen...hier mein quellcode

    #include "stdio.h"
    #include "ctype.h"
    #include "conio.h"
    
    main(int argc,char **argv)
    {
     if (argv[1][0] = '-') // Sucht nach dem Bindestreich , welcher Indikator für die Option (u oder l) ist
     {
    	 switch (argv[1][1]) // Geht auf die nächste Stelle nach dem Bindestreich um die Option zu prüfen
    	 {
    	 case 'u':
    		while(argv[2][0]!='\0') //...solange er nicht die abschliesende 0 des Strings findet
    		{ int zaehler_u=0; 
    			if (isupper(argv[2][zaehler_u])) //...sucht zeichenweise nach Grossbuchstaben...
    			{ putchar(argv[2][zaehler_u]); //...und gibt diese aus
    			zaehler_u++;}
    		}
    		break;
    
    	 case 'l':
    		while(argv[2][0]!='\0')
    		{ int zaehler_l=0;
    			if (islower(argv[2][zaehler_l])) //dasselbe Spiel wie bei 'u' nur mit is lower
    			{ putchar(argv[2][zaehler_l]);
    			zaehler_l++;}
    		}
    		break;
    
    	 default:
    
    	puts(argv); // wenn keine Arugmente angegeben werden, wird der String direkt wieder ausgegeben
    	break;
    	 }
    
     }
    	 getch();
    }
    

    Danke Schonmal!
    marsklaus



  • hier hab ich das mal umgeschrieben

    main(int argc,char **argv) 
    { 
    
    int zaehler_u = 0;
    int zaehler_l = 0;
    
     if (argv[1][0] == '-') // == und nicht =; = ist der zuweisungsoperator
     { 
         switch (argv[1][1])  
         { 
         case 'u':
    
            while(argv[2][zaehler_u]!='\0') { 
                if (isupper(argv[2][zaehler_u])) { 
                		putchar(argv[2][zaehler_u]); //
                    }
                    zaehler_u++;  //ausserhalb der if schleiffe - sonst gibts eine unendliche while()
            } 
            break; 
    
         case 'l': 
            while(argv[2][zaehler_l]!='\0') {  
                if (islower(argv[2][zaehler_l])) { 
                	putchar(argv[2][zaehler_l]); 
                    }
                zaehler_l++; 
            } 
            break; 
    
         default: 
    
        puts(argv[1]);  
        break; 
         } 
    
     } else 
         puts(argv[1]); // wurde ich hier auch noch mal setzten, sollte argv[1][0] nicht - sein
    }
    

    ist nicht gerade ideal eingerueckte source - aber das kannst du ja bei dir aendern. gerade faellt mir noch auf: du solltest dann immer noch ein newline an den gefilterten string setzen, sonst hast du die ausgabe von deiner prompt

    Gruss caspar



  • Hallo, ich wieder!

    Erst einmal Danke für die Antworten und sorry das ich so lange keine Rückmeldung gegeben habe, musste noch ein bischen Arbeit dazwischen schieben.

    Ich habe das Programm von Grund auf neu beschrieben, bekomme aber immer noch einen Speicherfehler...vielleicht seht ihr es euch mal an evt. kompiliert es sogar damit ihr den Fehler sehen könnt...wenn nicht kann ich euch auch die Meldung des debuggers posten...

    #include <stdio.h>
    #include <ctype.h>
    //#include <conio.h>
    
    main(int argc,char *argv[]) //Argumente kommen von der shell
    {
    int uflag=0; 
    int lflag=0;
    int cflag=0;
    int zaehler=0;
    int argc2=argc; // Ich sichere den Argument Counter
    int argc_mark=argc; //Hier dasselbe...
    while(argc2!=0)	//Solange der argv noch nicht auf 0 runtergezaehlt wurde
    {
    		if (argv[argc2][0] == '-') // Sucht nach dem - 
    			{	
    
    				argc_mark=argc2;    //Das hier ist dann die spätere Obergrenze für die Textverarbeitung
    								    //das erklärt sich wie folgt: argc wird von oben runtergezaehlt (siehe argc2--)
    								    //sobald er auf einem - trift ist klar das die darunter liegenden Argumente alle nur
    									//noch die Verarbeitungsparameter ala -c -u etc. sein können (Davon wird hier einfach ausgegangen
    									//Also haben wir fuer spaeter die Grenze ab wo die Verarbeitungsparameter aufhoeren und wo die
    									//Textparameter anfangen. Ich hoffe das war verständlich :)
    
    				switch (argv[argc2][1]) // Wird wird geugt welcher Verarbeitungsparameter eigentlich vorhanden ist.
    					{
    
    				case 'u': uflag=1;  //
    					break;		    //
    				case 'l': lflag=1;  //Ich denke das hier ist soweit klar
    					break;		    //
    				case 'c': cflag=1;  //
    					break;			//
    					}				
    
    			}
    	argc2--;			//wie oben erwähnt wird hier dann der counter runtergezaehlt.	
    	}
    
    argc2=argc;			//Hier setze ich den argc2 wieder zurueck.
    
    if ((uflag==1 && cflag==0 && uflag==0))			//Hier werden in den folgenden if schleifen geprueft ob die obrige schleife eine der flags ent. gesetzt hat
    	{
    		while(argc_mark!=argc )					//Solange der argc Zaehler hier nicht den wert des eigentlich Argument counters hat									
    		{ 
    			if (isupper(argv[argc_mark][zaehler]))		// hier wird zeichenweise ueberprueft ob das zeichen gross geschrieben ist						 
    			{ 
    				putchar(argv[argc_mark][zaehler]);								// und bei bedarf ausgegeben
    			}
    			zaehler++;									// Hier wir der Seperate Zaehler fuer die 2. Array stelle erhoert damit wird durch den string laufen koennen
    			if (argv[argc_mark][zaehler]=='\0' )		//Diese Schleife hat den Zweck damit man das argument erhoehen kann...also die erste stelle des arrays
    			{
    				argc_mark++;
    				zaehler=0;
    			}
    		}
    	}
    											// bei den anderen Schleifen ist nur die bearbeitung ent. abgewandelt...
    if ((uflag==0 && cflag==1 && uflag==0))
    	{
    		while(argc_mark!=argc )										
    		{ 
    			if (islower(argv[argc_mark][zaehler]))								 
    			{ 
    				putchar(argv[argc_mark][zaehler]);								
    			}
    			zaehler++;
    			if (argv[argc_mark][zaehler]=='\0' )
    			{
    				argc_mark++;
    				zaehler=0;
    			}
    		}
    	}
    
    if ((uflag==1 && cflag==0 && uflag==1))
    	{
    		while(argc_mark!=argc )										
    		{ 
    			if (islower(argv[argc_mark][zaehler]))								 
    			{ 
    				toupper(argv[argc_mark][zaehler]);
    
    			}
    			putchar(argv[argc_mark][zaehler]);
    			zaehler++;
    			if (argv[argc_mark][zaehler]=='\0' )
    			{
    				argc_mark++;
    				zaehler=0;
    			}
    		}
    	}
    if ((uflag==0 && cflag==1 && uflag==1))
    	{
    		while(argc_mark!=argc )										
    		{ 
    			if (isupper(argv[argc_mark][zaehler]))								 
    			{ 
    				tolower(argv[argc_mark][zaehler]);
    
    			}
    			putchar(argv[argc_mark][zaehler]);
    
    			zaehler++;
    			if (argv[argc_mark][zaehler]=='\0' )
    			{
    				argc_mark++;
    				zaehler=0;
    			}
    		}
    	}
    if ((uflag==1 && lflag==1))
    		{
    		puts("Bitte u ODER l als Verarbeitungsoperand benutzen. Nicht beide!");
    		}
    
    	// getch();
    }
    

    Der Debugger bricht bei :

    if (argv[argc2][0] == '-') // Sucht nach dem -
    

    mit diesem Fehler

    argv	0x00320c38	char * *
    0x00320c4c "uebung7_work.exe"	char *
    117 'u'	char
    ------------
    argv[argc2]	0x00000000 <Schlechtes Ptr>	char *
    CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden	char
    

    ab...

    Vielleicht findet ja jemand den knackpunkt 😞 ich finde ihn nicht...

    yours
    klaus



  • Hi,

    Deinen Fehler kann ich leider auch nicht finden. Aber ich glaube, Du hast die Aufgabe nicht ganz verstanden. Du sollst eine Textdatei über stdin einlesen, und nicht als Kommandozeilenparamter übergeben. D.h der Aufruf Deines Programmes muß sein:

    programm u c <datei.txt
    

    Die datei.txt wird in dem Falle so eingelesen, als Du das selbst eingeben würdest, sprich über stdin.

    dann würde ich an Deiner Stelle Festlegen, wann welcher Parameter zu erfolgen hat.
    z.B. der Erste Parameter muß 'u' oder 'l' sein, und der zweite evtl. 'c'.
    dann brauchst Du nur argv[1][0] auf 'u' und 'l' abfragen und argv[argc-1][0] auf 'c'. Der Rest ist falsch.

    Ich hab da auch mal etwas gebastelt. Wie schon gesagt, der erste parameter ist 'u' oder 'l', der zweite 'c' oder nicht, und dann die Textdatei mit '<' angeben (wie oben halt).
    Ich hab allerdings Funktionzeiger benutzt. Ich hoffe, Du kommst trozdem klar.

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include <ctype.h>
    
    //wie der Name schon sagt, macht nichts. Ist nur als Dummy gedacht, falls der
    //Text unformatiert ausgegeben werden soll
    int DoNothing(int c){ 
        return c;
        }
    //Da die Originalfunktionen isupper und islower nur boolsche Werte als
    //Antwort liefern, hab ich sie ein wenig erweitert, das sie jetzt im Falle 
    //eines true den Charakter zurückgeben und bei false einfach 0
    int MyIsUpper(int c){
           if (isupper(c)) return c;
           return 0;
           }
    int MyIsLower(int c){
           if (islower(c)) return c;
           return 0;
           }
    
    int main(int argc, char *argv[])
    {
       int (*manipulator)(int); // Zeiger auf MyIsUpper, MyIsLower, toupper, tolower
                                // Wenn man nur den Funktionsnamen ohne Klammern und
                                // Paramtern angibt, erhält man die Adresse der
                                // Funktion und kann sie in einem Zeiger speichern
    
       char c;                  // hier wird das eingelesene Zeichen gespeichert
    
       //Wenn Definitiv zu viele Argumente angegeben worden sind
       //Dabei zählt "<datei.txt" nicht mit. Denn das Programm bekommt
       //von dieser Angabe nichts mit
       //oder wenn das drei Argumente da sind, und das letzte nicht 'c' ist
    
       if( argc > 3 || (argc==3 && argv[argc-1][0] != 'c') ){
           printf("Die Argumente sind falsch .. Erklärung der Parameter");
           return -1;
           }
    
       //wenn kein Paramter angegeben wird, wird auch nichts gemacht
       if (argc==1) manipulator=DoNothing;    
    
       //wenn doch ein Parameter dann ab ins 'switch'
       else
       switch( argv[1][0] )
       {
       case 'u':
    
            //Wenn das zeite Argument 'c' ist, dann wird die Funktion toupper 
            //in den Zeiger geschieben, sonst MyIsUpper
    
            if ( argv[argc-1][0]=='c' ) manipulator = toupper;
            else manipulator = MyIsUpper;
    
         break;
    
       case 'l':     
    
            //siehe Oben
    
            if ( argv[argc-1][0]=='c' ) manipulator = tolower;
            else manipulator = MyIsLower;
         break;
    
       default:
    
          //Wenn weder 'u' noch 'l' als Paramter gegeben, dann Fehler
    
          printf("Die Paramter sind falsch.. Erklärung der parameter");
          return -1;
          break;
       }
    
      //Hier wird nunendlich die Datei eingelesen. Wie oben schon erklärt,
      //tut das Programm so, als wenn Du das ganze über die Tastatur eingibst.
      //Daher kannst Du das auch mit getchar abfragen.
      //Das '-1' entspricht einem EOF (End of File, Dateiende)
    
      // manipulator(c) führt nun die Funktion aus, die oben ausgewählt worden ist.
      while((c=getchar()) != -1)
      {
          if ( c = manipulator( c ) )
             putchar(c);
      }      
      return 0;
    }
    

    grüße Con@n


Anmelden zum Antworten