parameterstring auf zahlen überprüfen



  • hallo,
    ich will hab das problem das ich bei nem parameterstring überprüfen will ob er nur aus zahlen besteht.
    Hab das jetzt schon mit der funktion isdigit probiert allerdings bekomm ich da jetzt nen fehler wenn ich das programm compilier.
    Vlt könnt ihr mir ja bei der Fehlersuche helfen^^

    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    int *tablänge;
    
    void prueft(char a[], char b[]);
    
    int main(int argc, char *argv[]){
    int n=0;
    while(n<=argc){
    prueft(argv[n], argv[n+1]);
    n++;
    }
    }
    
    void prueft(char a[], char b[]){
    	char buffer[80];
    	int i=0;
    	int test =0;
    	strcpy(b,buffer);
    
    	if(strcmp(a, "-t")!=0){
    		while(buffer[i] != '\0'){
    			if(isdigit(buffer[i++])){
    			}else{
    				test++;
    			}
    			if(test==0){
          *tablänge= abs(atoi(b));
    			}
    		}
    	}
    }
    


  • Die Variable nicht "tablänge", sondern "tablaenge" nennen und schon ist alles in Butter. Zumindest beim Kompilieren. 😃



  • schon mal danke für die antwort, habs jetzt geändert, allerdings springts bei mir immer noch bei der funktion raus 😞



  • Vielleicht hilft das:

    int isDigitString(char *s){
        for (; *s; s++)
            if (*s < '0' || *s > '9') return 0;
        return 1;
    }
    


  • nwp2 schrieb:

    Vielleicht hilft das:

    int isDigitString(char *s){
        for (; *s; s++)
            if (*s < '0' || *s > '9') return 0;
        return 1;
    }
    

    er will ja ein char und kein string



  • Hallo,
    der Code wimmelt voller Bugs. 😃
    Du muss erstmal abfragen, ob überhaupt genug Argumente über stdin übergeben wurden.

    if ( argc <= 1 ) // Wenn nicht genug Argumente übergeben wurden...
    

    Dann möchtest du nicht das erste Argument argv[0] auf Zahl prüfen, denn da steckt meist nur der Programmname drin.
    Fang also mit n = 1 an.

    Dann musst du die Arraygrenzen einhalten,

    n<=argc
    

    greift über die Grenzen hinaus zu, es muss heißen:

    n<argc
    

    .
    Nächster Bug:

    prueft(argv[n], argv[n+1]);
    

    Auch hier überschreitest du die Arraygrenze.
    Schick die Parameter einzeln in die Funktion:

    prueft(argv[n]);
    

    Ein weiterer Fehler:
    Du dereferenzierst einen Zeiger, dem kein Speicher zugeordnet ist:

    *tablänge
    

    Außerdem würde ich keine Umlaute in Variablen benutzen, weil damit nicht jeder Compiler klar kommt.

    So könnte deine Funktion prueft aussehen:

    int is_integer ( char* s ) {
    	char* eptr = NULL;
    	strtol ( s, &eptr, 10 );
    	return *eptr;
    }
    

    Hier im Einsatz innerhalb von main:

    int main() { 
    	char* a = "123axc456", *b = "-123456"; // Simuliert z.B. argv[1], argv[2]
    	if ( is_integer(a) )
    		printf("Pfui! %s ist keine ganze Zahl!\n", a );
    	else 
    		printf("Ok! %s ist eine ganze Zahl!\n", a );
    
    	if ( is_integer(b) )
    		printf("Pfui! %s ist keine ganze Zahl!\n", b );
    	else 
    		printf("Ok! %s ist eine ganze Zahl!\n", b );
    	return 0;
    }
    

    Falls du auch Flieskommazahlen prüfen willst, tut das die Fuktion strtod (anstelle von strtol).
    Gruß,
    B.B.



  • so hab noch mal versucht die fehler so gut wie möglich zu beheben, allerdings springt das programm immer noch bei der überprüfung des strings auf zahlen raus 😞
    ich hoff mal es nicht zu unübersichtlich wenn ich die nicht relevanten programmteile einfach nur eingeklappt hab anstatt sie komplett rauszunehmen.

    #include <stdio.h>
    #include <conio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    int *tablaenge;
    int *verstoeße;
    int *hilfe;
    char *zieldatei[25];
    char zeilenlängenfehlermeldung[100][100], einrückfehlermeldung[100][100], einrückfehlermeldungzeile[100];
    
    void prueft(char a[], char b[]);
    void pruefv(char a[], char b[]);
    void pruefh(char a[]);
    void pruefzield(char a[]);
    void pruefz(char a[]);
    int isDigitString(char *s);
    
    int main(int argc, char *argv[]){
    int t=8, v=3, h=1, n=2;
    
    tablaenge=&t;
    verstoeße=&v;
    hilfe=&h;
    
    pruefzield(argv[2]);
    while(n<=argc){
    prueft(argv[n-1], argv[n]);
    pruefv(argv[n-1], argv[n]);
    pruefh(argv[n]);
    n++;
    }
    pruefz(argv[1]);
    
    }
    
    void prueft(char a[], char b[]){
    	if(strcmp(a, "-t")!=0){
    		if(isDigitString(b)==0){
          *tablaenge= abs(atoi(b));
    		}
    	}
    }
    
    void pruefv(char a[], char b[]){
    
    }
    void pruefh(char a[]){
    
    }
    
    void pruefzield(char a[]){
    
    }
    void pruefz(char a[]){
    }
    int isDigitString(char *s){ 
        for (; *s; s++) 
            if (*s < '0' || *s > '9') return 0; 
        return 1; 
    }
    


  • evtl. solltest du auch die stellen zählen?
    müsste es nicht heißen

    if(isDigitString(b)==1){ 
    statt
    if(isDigitString(b)==0){
    


  • axo das abs() kannst dir schenken da kommen eh keine negativen zahlen an...



  • Vielleicht willst Du folgendes:

    void prueft(char a[], char b[]){
    
    //  if(strcmp(a, "-t")!=0){
      if(strcmp(a, "-t") == 0){      // geht nun rein wenn string a == "-t" ist
    
    //    if(isDigitString(b)==0){
        if(isDigitString(b) != 0){   // geht nun rein wenn string b nur Zahlen ("0".."9") enthaelt
         *tablaenge= abs(atoi(b));
        }
    
      }
    
    }
    

    ?



  • gegenspammer schrieb:

    so hab noch mal versucht die fehler so gut wie möglich zu beheben, ...

    Ich gebs auf.



  • Big Brother schrieb:

    gegenspammer schrieb:

    so hab noch mal versucht die fehler so gut wie möglich zu beheben, ...

    Ich gebs auf.

    Nö, dann doch nicht . 🙂
    Ich habe versucht, dir ein ausbaufähiges Programmskelett für die Parameterauswertung zu schreiben. Der eine oder andere Tip steht in den Kommentaren. Vielleicht kannst du damit etwas anfangen.

    #include <stdio.h> 
    #include <stdlib.h> // strtoul
    // Wenn es keinen guten Grund gibt Zeiger zu benutzen, dann nimm lieber keine.
    // In deiner main Funktion wählst du int t=8, richtest den Zeiger darauf,
    // der Wert wird in isDigitString wieder überschrieben - ist also Sinnfrei. :)
    unsigned long tablaenge; // Muss ich wirklich global sein???
    // Funktion check_param_quantity. 
    // Nimmt inkrementiertes n entgegen.
    // Prüft, ob es mindestens noch einen Parameter zum Auswerten gibt.
    int check_param_quantity ( int argc, int n, char* param ) {
    	if ( n  < argc ) 
    		return 0; // Ok, der nächste Parameter kann ausgewertet werden.
    	printf ( "Fehler: fehlender Wert fuer Parameter: %s\n", param );
    	return 1; // Fehler, es fehlt ein Parameter.
    }
    // Funktion is_digit_string.
    // Prüft, ob nur Zahlen in param vorkommen und wandelt die Zeichenkette
    // nach unsigned long um.
    // Der umgewandelte Wert wird in der globalen Variable tablaenge gespeichert.
    int is_digit_string ( char* param ) { // Keine Kamelhöcker für Funktionsnamen, 
                                            // wir sind hier nicht im Java Forum.
    	char* s = param;
    	while (*s) {
    		if (*s < '0' || *s++ > '9') {
    			printf ( "Fehler: unerlaubtes Zeichen im Parameter: %s\n", param );
    			return 1; // Nicht ok. 
    		}
    	}
    	printf ( "%s enthaellt nur Zahlen ( %s <= ULONG_MAX? ).\n", param, param );
    	tablaenge = strtoul( param, NULL, 10 );
        return 0; // Ok, Zeichenkette enthält nur Zahlen.
    }
    
    int v_function ( char* param ) {
    	puts("v_function not implemented yet.");
    	return 0;
    }
    
    int h_function ( char* param ) {
    	puts("h_function not implemented yet.");
    	return 0;
    }
    
    int main() { 
    	int n = 0;
    ///////////////////////////////////////////////////////////////////////////////
    // Simulation einer Benutzereingabe an der Konsole, damit du dir an der Konsole
    // keinen Wolf tippen musst!
    	char* argv[] = { "C:\\test.exe", 
    						"-t", "1234",
    							"-v", "irgendwas nach v",
    									"-h", "irgendwas nach -h",
    										"-t", "12a34" };
    // Berechnet die Anzahl der Parameter.
    	int argc = sizeof argv/sizeof *argv; 
    ///////////////////////////////////////////////////////////////////////////////
    /*						Auswertung der Parameter							 */			
    ///////////////////////////////////////////////////////////////////////////////
    // argv[0] hat meistens den Pfad zur exe:
    	if ( argc >= 1 )
    		puts ( argv[n] );
    	n = 1;
    	// Hier gilt es immer noch, die Arraygrenze einzuhalten: n < argc !!!!!
    // Mach dir das Leben nicht so schwer, Werte die Parameter einzeln aus!
    // Deine Funktionen geben Werte zurück, also werte sie aus!
    	while ( n < argc ) {
    /////////////////////// Abfrage auf -t ////////////////////////////////////////
    		if ( strcmp ( argv[n], "-t" ) == 0 ) {
    			if ( check_param_quantity ( argc, n, argv[n++] )) // Aufruf inkrementiert n!
    				break; // Es fehlt ein Wert für Parameter -t
    			if ( is_digit_string ( argv[n] ) )
    				break; // Fehler, mindestens ein Zeichen ist keine Zahl.
    		}
    /////////////////////// Abfrage auf -v ////////////////////////////////////////
    		if ( strcmp ( argv[n], "-h" ) == 0 ) {
    			if ( check_param_quantity ( argc, n, argv[n++] )) // Aufruf inkrementiert n!
    				break; // Es fehlt ein Wert für Parameter -h
    			if ( h_function ( argv[n] ) )
    				break; // Fehler.
    		}
    /////////////////////// Abfrage auf -h ////////////////////////////////////////
    		if ( strcmp ( argv[n], "-v" ) == 0 ) {
    			if ( check_param_quantity ( argc, n, argv[n++] )) // Aufruf inkrementiert n!
    				break; // Es fehlt ein Wert für Parameter -v
    			if ( v_function ( argv[n] ) )
    				break; // Fehler.
    		}
    		n++;
    	} // while ( n < argc )
    	printf ( "Es wurden %d Parameter bearbeitet.\n", argc );
    	return 0;
    }
    /*
    	Deinem Code nach zu urteilen, wird das Programm noch ne ganze Ecke größer.
    	Eventuell empfiehlt es sich also, alles was in der main steht, in eine separate 
    	Funktion auszulagern.
    */
    

Anmelden zum Antworten