strtok, code optimieren



  • hi,
    hab einen string den will ich zerlegen, dabei dient ; als trennerzeichen...die teilstrings gebe ich in ein array von structs..
    wollte fragen, ob man das erste strtok auch irgendwie in die while schleife verpacken kann? mir ist grad nichts besseres eingefallen...verzeiht mir das count und cin.get() 😉

    bye

    struct foo
    {
    	char var[20];
    };
    
    int main() 
    {
    	foo f[4];
    	int counter = 0;
    	char text[] = "Mein;Name;ist;Hans";
    	char *str = strtok(text, ";");
             strcpy(f[counter++].var, str);
    
    	while (str != NULL)
    	{
    		str = strtok (NULL, ";");
    		if(str != NULL) {
    			strcpy(f[counter++].var, str);
    		}
    	}
    
    	cout << f[3].var << endl;
             cin.get();
             return 0;
    }
    


  • könnte man

    char *str = 0;
    ...
    str = strtok (str?0:text, ";");

    dabei muss es aber dann do{...}while() heißen



  • nehmen wir an
    der string schaut so aus, befindet sich in einer textdatet mit mehreren zeilen:

    char text[] = "1101|Fleischwurst Knobl.|101|48|1300|900|23|5|2005";
    1101 = Art_Nr
    Fleischwurst Knobl. = Abez
    101 = Fil_Nr
    48 = Menge
    1300 = VK_Preis
    900 = Ks_Preis
    23|5|2005 = datum

    und ich will den string in die structur einlesen:

    struct satz {
    	short Art_Nr, Fil_Nr;
        char Abez[100];
         unsigned short int Datum;
        long Menge, Vk_Preis, Ks_Preis;
    };
    

    wie würdest du das am besten machen? weisst du was besseres als 7 mal strtok hintereinander?;-)

    bye



  • ...mit dem richtigen Formatstring gehts auch mit fscanf.



  • hm nee, bei der Abez würde ein %s formatstring versagen (bricht beim leerzeichen ab).

    entweder strtok(), wobei ein loop wegen der verschiedenen datentypen (string, zahlen, ...) unsinn wäre.

    oder du machst dir ein eigenes strtok()
    das würd ich aber lieber sein lassen, weils wohl den aufwand nicht wert ist, wenn du nur eine tabelle einlesen willst.

    schon ne idee, wie du die datensätze im speicher halten willst?
    einfaches struct array, indexliste, verkettete liste, hashliste, (binärer) baum,...?



  • wolfi schrieb:

    wollte fragen, ob man das erste strtok auch irgendwie in die while schleife verpacken kann?

    int main() 
    {
     foo f[4];
     int counter = 0;
     char text[] = "Mein;Name;ist;Hans";
     char *str = strtok(text, ";");
     strcpy(f[counter++].var, str);
    
     for(char *str = strtok(text, ";") ; str != NULL ; str = strtok (NULL, ";"){
      strcpy(f[counter++].var, str);
     }
    
     cout << f[3].var << endl;
     cin.get();
     return 0;
    }
    


  • volkard, danke für deinen disclaimer 🙂

    da du cin benutzt hast, lass ich das mal drin.
    ich hab nichts gegens mischen, aber andere vielleicht...

    int main()
    {
    	foo f[4];
    	int counter = 0;
    	char text[] = "Mein;Name;ist;Hans";
    	char *str = 0;
    
    	while ((str = strtok(str?0:text, ";")))
    		strcpy(f[counter++].var, str);
    
    	cout << "count = " << counter << endl;
    	for (int i = 0; i < counter; ++i)
    		cout << "f[" << i << "].var = \"" << f[i].var << "\"" << endl;
    
    	return 0;
    }
    


  • c.rackwitz schrieb:

    volkard, danke für deinen disclaimer 🙂

    also mich hat gestern früh mein strtok persönlich angerufen und gesagt, daß es sich in einer for-schleife am wohlsten fühlt. und daß ich euch das allen sagen soll.

    dann hab ich wohl vor der for-schleife noch initialisierung der alten while-schleife gelassen, was nicht gut war und ein ) vergessen.

    int main() 
    { 
     foo f[4]; 
     int counter = 0; 
     char text[] = "Mein;Name;ist;Hans"; 
    
     for(char *str = strtok(text, ";") ; str != NULL ; str = strtok (NULL, ";")){ 
      strcpy(f[counter++].var, str); 
     } 
    
     cout << "count = " << counter << endl; 
     for (int i = 0; i < counter; ++i) 
      cout << "f[" << i << "].var = \"" << f[i].var << "\"" << endl; cin.get(); 
     return 0; 
    }
    

    kann aber sein, daß mein strtok von c++ verwöhnt ist und ein strtok für c lieber mit while und ?: leben sollte.



  • man kann schon es mit scanf() machen. die steuersequenz %[...] hat den selben effekt wie %s, endet allerdings nicht nach dem ersten whitespace und trimmt den string auch nicht. darüber hinaus kann man auch noch angeben, welche zeichen bzw bis zu welchem zeichen die eingabe gelesen werden soll. zb liest "%[^|]" alle zeichen bis exclusive dem ersten '|' ein, dh auch whitespaces.

    siehe auch http://www.openbsd.org/cgi-bin/man.cgi?query=scanf&apropos=0&sektion=0&manpath=OpenBSD+Current&arch=i386&format=html


Anmelden zum Antworten