-
        

Ergebnis 1 bis 4 von 4

Thema: C und die Strings

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    13.05.2007
    Alter
    26
    Beiträge
    183

    C und die Strings

    Anzeige

    Hallo Ihr!

    Ich versuche grade für meine SD-Karte eine Art pseudo-xml zu realisieren. Nach dem Muster
    <tagname=wert>
    sind da Werte drauf. Allerdings habe ich arge probleme mit den Strings in C. Folgendes funktioniert irgendwie nicht.

    Code:
    // Findet das nächste Zeichen mit dem übergebenen Wert in einer Datei, ansonsten wird  0 zurückgegeben
    unsigned long int tpx_find_char(char s) {
    	unsigned long int count=0;
    	unsigned long int seek=file.length;
    	char p;
    	do {
    		count++;
    		p = ffread();
    	} while (!((--seek<0) || (p==s)));
    	return count;
    }
    
    int tpx_read_tag(char* name, char* value) {
    	char *s;
    	int count;
    	int i=0;
    	 
    	// Wenn keine Datei offen ist, abbrechen
    	if (!fileopened) {
    		return 1;
    	}
    		
    	// Beginn des tags finden
    	tpx_find_char('<');
    	// Zeichen bis zum Ende des Namens (also bis zum '=') zählen
    	count = (int) tpx_find_char('=') -1;
    	// zurück setzen
    	file.seek -= count;
    
    	// Daten Einlesen...
    	s = (char*) malloc(count+1);
    	
    	for (i=0; i<count; i++) {
    		s[i] = ffread();
    		s[i+1] = '\0'; 
    	}
    	// und ausgeben.
    	strcpy(name, s);
    	free(s);
    
    	// Zeichen bis zum Ende des Tags (also bis zum '>') zählen
    	count = (int) tpx_find_char('>');
    	// zurück setzen
    	file.seek -= count;
    	
    	// Daten Einlesen...
    	s = (char*) malloc(count+1);
    	
    	for (i=0; i<count; i++) {
    		s[i] = ffread();
    		s[i+1] = '\0'; 
    	}
    	for (i=0; i<count; i++) {
    		s[i] = ffread(); 
    	}
    	// und ausgeben.
    	strcpy(value, s);
    	free(s);
    	
    	return 0;
    }
    tpx_find_char geht ganz gut, aber das einlesen der Zeichen von der SD in einen String funktioniert nicht ansatzweise...

    Danke für Hilfe,
    Bääääär

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Ich verstehe nicht so ganz, warum du das so kompliziert machst. Die Ergebnisse werden doch letztlich nach name und value geschrieben, wobei die Funktion einfach davon ausgeht, dass dort schon jeweils genug Platz vorhanden sein wird. Wozu also dieses komplizierte Zwischenspeichern mit Längenermittlung fürs malloc etc? Warum schreibst du die Zeichen nicht gleich direkt nach name und value?

    Pseudocode:
    Code:
    skip bis '<'
    while (zeichen aus file nicht '=')
        schreibe zeichen nach name
    terminiere name
    while (zeichen aus file nicht '>')
        schreibe zeichen nach value
    terminiere value
    MfG
    Stefan

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    13.05.2007
    Alter
    26
    Beiträge
    183
    Hmm, habs jetzt so versucht aber in den Rückgabewerten steh nur Müll und der Compiler gibt mir bei strcat Warnungen aus, weil ich aus einem unsigned char einen (char*) mache...

    Funktionen:
    Code:
    // Findet das nächste Zeichen mit dem übergebenen Wert in einer Datei, ansonsten wird  -1 zurückgegeben
    unsigned long int tpx_find_char(char s) {
    	unsigned long int count=-1;
    	unsigned long int seek=file.length;
    	char p;
    
    	do {
    		count++;
    		p = ffread();
    
    	} while (!((--seek<0) || (p==s)));
    	
    	return count;
    }
    
    int tpx_read_tag(char* name, char* value) {
    	char s;
    	 
    	// Wenn keine Datei offen ist, abbrechen
    	if (!fileopened) {
    		return 1;
    	}
    		
    	// Beginn des tags finden
    	tpx_find_char('<');
    	
    	unsigned long int seek=file.length;
    	s = ffread();
    	seek--;
    	do {
    		strcat(name, (char*) s);
    		s = ffread();
    	 } while ((s=='=') || !(seek--));
    	
    	s = ffread();
    	seek--;
    	do {
    		strcat(value, (char*) s);
    		s = ffread();
    	 } while ((s=='>') || !(seek--));
    	
    	
    	return 0;
    }
    Und der Aufruf:
    Code:
    int main(void) {	 
    	
    	char *tag;
    	char *value;
    	
    	lcd_init();
    	lcd_clear();
    	
    	sd_init();
    	
    	lcd_clear();
    	
    	tag = malloc(30);
    	value = malloc(30);
    	tag[0] = '\0';
    	value[0] = '\0';
    	
    	char file[] = "testdat.txt";
    	fat_str(file);
    	ffopen(file);
    	lcd_clear();
    	tpx_read_tag(tag, value);
    	lcd_string("T: ");
    	lcd_string(tag);
    	lcd_set_cursor(0,1);
    	lcd_string("V: ");
    	lcd_string(value);
    	_delay_ms(1000);
    	lcd_clear();
    	
    	tag[0] = '\0';
    	value[0] = '\0';
    	
    	tpx_read_tag(tag, value);
    	lcd_string("T: ");
    	lcd_string(tag);
    	lcd_set_cursor(0,1);
    	lcd_string("V: ");
    	lcd_string(value);
    	_delay_ms(1000);
    		
    	ffclose();
    	
    	return 0;
    }

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Code:
       unsigned long int seek=file.length;
       s = ffread();
       seek--;
    // Ich vermute, damit willst du erreichen, nicht über das Ende der Datei "hinauszulesen".
    // Geht so aber nicht, weil du nicht berücksichtigst, wo in der Datei du gerade bist.
       do {
          strcat(name, (char*) s);
    // Schon wieder zu kompliziert gedacht (und das Gedachte auch falsch realisiert).
    // Warum nicht einfach *name++ = s; ?
    // (dann aber nach der Schleife die Terminierung nicht vergessen: *name = 0; )
          s = ffread();
        } while ((s=='=') || !(seek--));
    // while heißt "während" und nicht "bis".
    // Deine Bedingung hat die falsche Logik.
    MfG
    Stefan

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •