INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Funktion ähnlich variabel definieren wie sprintf
22.02.2015, 18:53 (Dieser Beitrag wurde zuletzt bearbeitet: 22.02.2015 18:53 von HaWe.)
Beitrag #1
Funktion ähnlich variabel definieren wie sprintf
hallo,
wie kann ich selber eine Funktion schreiben, die ähnlich variable ist wie sprintf?

ihr sollen z.B. alle Variablen genau so übergeben werden können, wie man sie auch sprintf übergeben würde, (variable Anzahl, variable Tyoen), nur soll sie damit etwas anderes machen als es sprintf tut.

Ziel:
ich möchte beispielsweise printf und fprintf als Funktionen in Sketch implementieren


Hat jemand eine Idee?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
22.02.2015, 23:14
Beitrag #2
RE: Funktion ähnlich variabel definieren wie sprintf
Hi,
schau Dir das mal an: http://www.varesano.net/blog/fabio/funct...ts-arduino.
Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 10:32
Beitrag #3
RE: Funktion ähnlich variabel definieren wie sprintf
danke, das wird wohl eine echte Herausforderung... Undecided


fangen wir mit dem verlinkten Beispiel mal an...

Code:
/*
program: demo multi var args
0001
Sketch: 1.6.0
This example code is in the public domain.
*/

#include <stdarg.h>
#include <stdio.h>

  

/* this function will take the number of values to average
   followed by all of the numbers to average */
float average ( int num, ... )
{
    va_list arguments;                    
    float sum = 0;

    /* Initializing arguments to store all values after num */
    va_start ( arguments, num );          
    /* Sum all the inputs; we still rely on the function caller to tell us how
     * many there are */
    for ( int x = 0; x < num; x++ )        
    {
        sum += va_arg ( arguments, double );
    }
    va_end ( arguments );                  // Cleans up the list

    return sum / num;                      
}




void setup()
{
  float avg;
  
  Serial.begin(9600);
    
  avg = average( 3, 12.0, 8.0, 4.0 );
  Serial.println(avg);  // 24/3 == 8.0
  
  avg = average( 5, 3.0, 20.0, 2.0, 6.0, 4.0 );
  Serial.println(avg);  // 35/5 == 7.0
  
  
}

void loop()
{
  // nothing happens after setup
}

Ausgabe erfolgt korrekt als
8.00
7.00

gerade festgestellt: gibt man nicht 20.0 ein sondern 20, übersieht er es einfach!


Jetzt weiter:
Im obigen Beispiel wird ja die Anzahl der Argumente mit übergeben, bei printf passiert das ja nicht, hier zählt er sie irgendwie selber.
Kann man das auch im obigen Code nachbilden, dass die Funktion also nur lautet
Code:
float average ( ... ) //
und er zählt die Anzahl der Argumente selbstständig?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 11:52
Beitrag #4
RE: Funktion ähnlich variabel definieren wie sprintf
Hi,
das mit dem 20.0 und 20 könnte folgendes sein: 20 hat den Datentyp int, während 20.0 float oder double hat. Da Du explizit nach double fragst könnte das ein Problem sein. Ich kann mir sogar vorstellen, dass die nachfolgenden Parameter komplett daneben gehen.
Von wegen Anzahl der Argumente: printf kennt die Anzahl der Argumente und deren Datentypen aus dem Format-String, der immer als erster Parameter angegeben werden muss. Ich glaube nicht, dass man die Anzahl und die Datentypen anders ermitteln kann. Ich glaube, dass bei "..." die Funktion einfach nur einen Zeiger auf den Anfang der Aktualparameter bekommt. Wenn man mal von virtuellen Methoden in Klassen absieht, hat C(++) keinen Mechanismus zum Feststellen eines Datentyps zur Laufzeit.
Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 11:55 (Dieser Beitrag wurde zuletzt bearbeitet: 23.02.2015 11:57 von HaWe.)
Beitrag #5
RE: Funktion ähnlich variabel definieren wie sprintf
hi, das hat sich ja gerade überschnitten... Wink
falls das jetzt ohne die explizite Anzahl nicht so einfach geht, kann man das auch erstmal zurückstellen.
Eventuell kann man sich später auch anders behelfen, z.B. die Anzahl der "%" im formatstr zählen oder was auch immer...



Aber die nächste Frage kommt sogleich:

wie kann ich der Funktion (nennen wir sie foo) verklickern, dass jetzt eine Liste mit ganz verschiedenen Variablentypen kommt, und in welcher Reihenfolge?
Vermutung:
Das wird möglicherweise auch nur über eine vorherige Unterfunktion gehen, die die einzelnen Zeichen im Formatstring auswertet, oder?

Also in der Art
Code:
foo(int num, char * fmtstr, ...){

   int vtype[10], numcnt;
   int len = strlen(fmtstr);
   for(int i=1; i<len; ++i) {
      if(fmtstr[i-1]=='%') {
         numcnt++;
         vtype[int j++] = fmtstr[i];
      }
   }

   //
   //

}


Dann hätte man mit der Anzahl der %'s sogar auch einen Hinweis auf die Anzahl der Argumente und in vartype[] stehen nacheinander ihre var-Typen.


Das werde ich mal ausprobieren
dann sehen wir weiter...
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 12:00
Beitrag #6
RE: Funktion ähnlich variabel definieren wie sprintf
(23.02.2015 11:55)HaWe schrieb:  wie kann ich der Funktion (nennen wir sie foo) verklickern, dass jetzt eine Liste mit ganz verschiedenen Variablentypen kommt, und in welcher Reihenfolge?
Vermutung:
Das wird möglicherweise auch nur über eine vorherige Unterfunktion gehen, die die einzelnen Zeichen im Formatstring auswertet, oder?
Genau, siehe meinen letzten Beitrag.
Wenn man eine überschaubare Liste von Möglichkeiten hat, dann kann man Funktionsnamen auch überladen. D.h. Du kannst einmal
void foo(char*)
und einmal
void foo(int)
definieren, mit jeweils eigenem Coding.
Ansonsten gibt es noch die Möglichkeit mit Templates, dann werden diese Funktionen sozusagen automatisch erzeugt, wenn sie gebraucht werden.
Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 12:17 (Dieser Beitrag wurde zuletzt bearbeitet: 23.02.2015 12:55 von HaWe.)
Beitrag #7
RE: Funktion ähnlich variabel definieren wie sprintf
ja, dann werde ich mal da dran machen.
Überladen scheidet wohl aus, denn es gibt ja bei 0-9 möglichen verschiedenen Variablen-Anzahlen = max 10 Stellen mit (signed/unsigned) 8/16/32-bit ints und 32/64 bit floats und dann noch "strings"
=> insgesamt 9^10 verschiedene Kombinationsmöglichkeiten... (oder 10^9? egal...)
Also werd' ich mal versuchen, eine einfache Version von fmtstrings zu verwenden!

[OT]
Das Konzept "Überladen" war mir übrigens auch bisher neu bzw. unklar, daher hatte ich bisher auch das seltsame Verhalten von Serial.print mit signed oder unsigned chars auch nicht verstanden...
[/OT]

als ein erster praktischer Teilerfolg:

ein kleines Tool, mit dem man eine variable Reihe von Strings zusammenkopieren (=aneinandersetzen) kann, ohne immer kompliziert einzelne strcats oder einzelne aneinandergesetzte Serial.print() verwenden zu müssen:
Code:
char * strconcat ( int num, ... )

Als Übergabeparameter braucht man nur angeben:
1: die Anzahl der einelnen Strings, die nun folgt, und
2. die einzelnen zusammenzukopierenden Strings, getrennt durch Kommata:

Code:
/*
program: demo multi var args
multivargs 0003
Sketch: 1.6.0
This example code is in the public domain.
*/

#include <stdarg.h>
#include <stdio.h>  

// concatening a various number of single strings to 1 single large one:
char * strconcat ( int num, ... )
{
    va_list arguments;                    
    char str[1024];

    /* Initializing arguments to store all values after num */
    va_start ( arguments, num );          
    
    // concat all the strings as  many as there are
    strcpy(str,"");
    for ( int i = 0; i < num; ++i )  {
        strcat(str, va_arg ( arguments, char * ) );
    }
    va_end ( arguments );                  // Cleans up the list

    return str;                      
}




void setup()
{
  char * sbuf;
  
  Serial.begin(9600);
    
  strconcat( 4, "hello"," ","world","!" );
  Serial.println( strconcat(4, "hello"," ","world","!" ) );
  Serial.println( strconcat(2, "heute ist der ", "22.2.2015") );
  
  
}

void loop()
{
  // nothing happens after setup
}


Share and enjoy! Smile
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
23.02.2015, 15:46 (Dieser Beitrag wurde zuletzt bearbeitet: 23.02.2015 15:50 von HaWe.)
Beitrag #8
RE: Funktion ähnlich variabel definieren wie sprintf
so jetzt aber, nächste Stufe:


wieder concat, aber mit einem Separator-String getrennte, per itoa formatierte Zahlen (Separator kann eine Variable oder eine Konstante sein):

Code:
/*
program: demo multi var args
multivargs 0005
Sketch: 1.6.0
This example code is in the public domain.
*/

#include <stdarg.h>
#include <stdio.h>  




char * strconcatsep ( int num, char * separator, ... )
{
    va_list arguments;                    
    char str[1024];

    /* Initializing arguments to store all values after num */
    va_start ( arguments, num );          
    
    // concat all the strings as  many as there are
    strcpy(str,"");
    for ( int i = 0; i < num; ++i )  {
        strcat(str, va_arg ( arguments, char * ) );
        if(i<num-1) strcat(str, separator);
    }
    va_end ( arguments );                  // Cleans up the list

    return str;                      
}





void setup()
{
  char * sptr;
   char sbuf1[20],sbuf2[20],sbuf3[20];
  char s[]=".";
  
  int day=22, month=02, year=2015;
  
  Serial.begin(9600);
  
  sptr=strconcatsep(3, s, "22", "02", "2015" );
  Serial.println( sptr );

  sptr=strconcatsep(3, ".", itoa(day,sbuf1,DEC), itoa(month,sbuf2,DEC), itoa(year,sbuf3,DEC) );
  Serial.println( sptr );
  
  
}

void loop()
{
  // nothing happens after setup
}


Ausgabe:
Code:
22.02.2015
22.2.2015


außer
sptr=strconcatsep(3, ".", itoa(day,sbuf1,DEC), itoa(month,sbuf2,DEC), itoa(year,sbuf3,DEC) );
Serial.println( sptr );

geht auch direkt:
Serial.println( strconcatsep(3, ".", itoa(day,sbuf1,DEC), itoa(month,sbuf2,DEC), itoa(year,sbuf3,DEC) );
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Funktion mit Parameterübergabe - u8g torsten_156 8 398 22.06.2016 18:53
Letzter Beitrag: Pit
  Probleme mit sprintf() und dtostrf() GMBU 11 808 22.06.2016 10:52
Letzter Beitrag: GMBU
  Funktion in Loop einmalig ausführen Haustechno 4 646 09.03.2016 22:43
Letzter Beitrag: Haustechno
Star Infrarot variabel nutzen ??? Mourti 7 409 18.02.2016 18:13
Letzter Beitrag: Mourti
  HC-05 Modul auf Funktion prüfen. arduinofan 2 365 03.02.2016 19:18
Letzter Beitrag: arduinofan
  Eine Funktion vorher definieren ? arduinofan 23 2.019 30.12.2015 08:42
Letzter Beitrag: amithlon
  Funktion/Methode mit mehr als einem Ausgangswert Marduino_UNO 18 1.256 20.10.2015 10:30
Letzter Beitrag: Marduino_UNO
  Array während Laufzeit neu definieren BennIY 2 646 26.08.2015 19:22
Letzter Beitrag: BennIY
  PulseIn-Funktion unklar alpenpower 6 1.284 24.07.2015 10:05
Letzter Beitrag: Scherheinz
  auslagern von Funktion aus der void loop? MaHaI976 19 2.880 22.06.2015 20:38
Letzter Beitrag: MaHaI976

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste