Skocz do zawartości

strtok_r() jak dołączyć bibliotekę


_LM_

Pomocna odpowiedź

Sprawdzę jak się uporam z problemem z wątku 😉 no tak by wyglądał prostacki, napisany kolanie a już działający program gadający. 

#Region  Project Attributes 
	#ApplicationLabel: B4A Example
	#VersionCode: 1
	#VersionName: 
	'SupportedOrientations possible values: unspecified, landscape or portrait.
	#SupportedOrientations: unspecified
	#CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes 
	#FullScreen: False
	#IncludeTitle: True
#End Region

Sub Process_Globals
	'These global variables will be declared once when the application starts.
	'These variables can be accessed from all modules.
	Private xui As XUI
	
	Dim tts1 As TTS
End Sub

Sub Globals
	'These global variables will be redeclared each time the activity is created.
	Private EditText1 As EditText
End Sub

Sub Activity_Create(FirstTime As Boolean)
	
	
	Activity.LoadLayout("Layout")
	tts1.Initialize("TTS1")
	If tts1.SetLanguage("pl","") Then
		ToastMessageShow("Język Polski jest dostępny",True)
	End If
End Sub

Sub Activity_Resume
	If tts1.IsInitialized = False Then
		tts1.Initialize("TTS1")
	End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)
	tts1.Release
End Sub


Private Sub EditText1_EnterPressed
	tts1.Speak(EditText1.Text, True)
	EditText1.SelectAll
End Sub

 

Link do komentarza
Share on other sites

(edytowany)

W kwestii problemu wątku -> w sumie błąd był po mojej stronie gdyż funkcja nawet nie miała okazji wejść w strtok_r. Zauważyłem to po krótkim odpoczynku od kodu oraz po pogawędce z @ethanak co można zobaczyć w tym poście. /2 Był też pewien błąd w aplikacji (androidowa, piszę ją równolegle) która współpracuje z tym urządzeniem. Co ciekawe VSC nadal mi podświetla że strtok_r jest niezdefiniowany jednak kompiluje już bez ujadania 😉. Dla ciekawskich moje rozwiązanie funkcji parsującej, ciekawostką może być to że tablicuję spodziewane nadchodzące stringi wraz ze wskaźnikami na funkcje które mają je obsługiwać. Aha i jeśli ktoś widzi, że coś można poprawić to chętnie się o tym dowiem. Na pewno można czytać wskaźniki na funkcje oraz stringi przypisane czytać bezpośrednio z flasch jak? W AVR są makra pgm_read_word a czy tutaj też?

Dzięki @ethanak za zainteresowanie postem.



#include <Arduino.h>
#include <WiFiUdp.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "udpParse.h"
#include "../mem/memo.h"


enum parametr{brakznaku =-2,brak,zapis,odczyt};

WiFiUDP Udp;

unsigned int localUdpPort = 32000;
 
char packetBuffer[];

void sendOk( char * par,char * str,int p);
void Name(char * par,char * str, int p);
void ListaNr(char * par,char * str, int p);

void udpResponse(char * s);

 //char *sTrtok_r(char * s, const char * sep, char ** p);



funct_t funkcje[] = { 
{"UDP?","UDP_OK",brak,sendOk},
{"NAME","+NAME=",brak,Name}, // wysyla nazwe jesli zapisana w eeprom
{"LISTANR","+LISTANR=",brak,ListaNr} // zapisuje lub wczytuje liste numerow 

};

//UDP -> UDP_OK // potw polaczenia z serwerem
//NAME? -> +NAME= // odczyt nazwy automatu
//NAME= -> +NAME= OK
//+LISTANR? -> wysyla liste numerow zapisanych w eeprom
//LISTANR = -> dostaje liste nr z UDP

int testUdpString(char * str){


if(0 == strcmp(funkcje[0].nazwa,str)){ // jesli UDP
    funkcje[0].fCallback(NULL,(char*)funkcje[0].response,funkcje[0].parametr); // jesli prosta nazwa
         return 0;
}


size_t tabSize = sizeof(funkcje)/sizeof(funct_t); // zwraca rozmiar tab funkcji 

int resp = brakznaku; // response czy string jest prawidlowy?
char * ptr[2] = {NULL, NULL}; 

if(NULL != strpbrk(str,"?")){ // jesli zapytanie
            resp = odczyt;
            ptr[0] = strtok(str,"?");
       
}else if(NULL != strpbrk(str,"=")){
             resp = zapis;
           ptr[0] = strtok(str,"=");
           ptr[1] = strtok(NULL,"=");
}


    if(resp == brakznaku) return - 1;


    for (uint8_t i = 0; i < tabSize; i++){ // szukanie od 1 indeksu bo jesli zerowy to funkcja i tak przerwana
    if(0 == strcmp(funkcje[i].nazwa,ptr[0])){
        funkcje[i].fCallback(ptr[1],(char*)funkcje[i].response,resp); //przypisanie i wywolanie callback
        return 0;
        
    }

    }
return - 1;
}


void sendOk(char * par, char * str,int p){
udpResponse(str);
}

void Name(char * par,char * str,int p){
    
    switch (p)
    {
    case odczyt:
     
     char bf[50];
     memset(bf,0,sizeof(bf)/sizeof(char));
     strcpy(bf,str);
     strcat(bf,daneEeprom.nazwa); 
     
     udpResponse(bf);
   //  udpResponse(str);
        break;
    case zapis:
    memset(daneEeprom.nazwa,0,sizeof(daneEeprom.nazwa)/sizeof(char)); // kasowanie ram
    strcpy(daneEeprom.nazwa,par); // kopiowanie do n nowej nazwy
    

    Serial.print("Nowa nazwa: ");
    eSave(); // zapis do eeprom
    Serial.println(daneEeprom.nazwa);
    udpResponse(daneEeprom.nazwa);
    break;
    default:
    break;
    }
}


void ListaNr(char * par,char * str, int p){
    switch (p)
    {
    case odczyt:
            char bf[300];
     memset(bf,0,sizeof(bf)/sizeof(char));   
    if(daneEeprom.saved == - 1){

     strcpy(bf,str);
     strcat(bf,"PUSTA");
     udpResponse(bf);
    }else{
       strcpy(bf,str);
    //   strcat(bf,"ZAPISANYCH:"); //+LISTANR=3:2>123213#2>039284203984#3>22345#
        char b2[4];
        strcat(bf,itoa(daneEeprom.saved,b2,10));
        strcat(bf,":");

        for(uint8_t i = 0; i < daneEeprom.saved; i++){ // wysylka nr
 
        
        strcat(bf,itoa(daneEeprom.numery[i].param,b2,10));
        strcat(bf,">");
        strcat(bf,daneEeprom.numery[i].nTel);
        strcat(bf,"#");

        }
        udpResponse(bf);
    }

        break;
    case zapis:
                {
                  //  Serial.println(par);
        
        char * p = strtok(par, "#");
        char * pptr[10];
        char * reszta[10];
       
        uint8_t l = 0;
        while (p)
        {
                   pptr[l] = p;
        p = strtok(0, "#");
        l++;
        }
        daneEeprom.saved = l; // ile zapisanych

        for(uint8_t i = 0; i < l; i++){
            daneEeprom.numery[i].param = atoi(strtok_r(pptr[i],">",&reszta[i]));
           
        //   Serial.println(reszta[i]);
           strcpy(daneEeprom.numery[i].nTel,reszta[i]); 
        }
        eSave(); // zapis struct do eeprom
        }
        break;
        default:
        break;
    }
}           

void udpTest(){
int packetSize = Udp.parsePacket();

if(packetSize){
int len = Udp.read(packetBuffer,255);
if(len > 0){
  packetBuffer[len] = 0;
}
       // Serial.printf("UDP packet contents: %s\n", packetBuffer); // co przylecialo po UDP
        int w = testUdpString(packetBuffer);
        if(-1 == w){
            udpResponse((char*)"Nieznane polecenie");
        }
    }
}

void udpResponse(char * s){
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(s);
    Udp.endPacket();
}



// char *sTrtok_r(char * s, const char * sep, char ** p)
// {
// 	if (!s && !(s = *p)) return NULL;
// 	s += strspn(s, sep);
// 	if (!*s) return *p = 0;
// 	*p = s + strcspn(s, sep);
// 	if (**p) *(*p)++ = 0;
// 	else *p = 0;
// 	return s;
// }

plik .h

#ifndef _UDPPARSE_H_
#define _UDPPARSE_H_

#include <Arduino.h>
#include <WiFiUdp.h>

typedef void(*ptrfun)(char*,char *,int); // wskaznik na funkcje wywolana kiedy dane poprawne

typedef struct
{
const char * nazwa;     
const char * response;  
int parametr;
ptrfun fCallback;
}funct_t;

extern WiFiUDP Udp;

int testUdpString(char * str);
void udpTest(void);

extern unsigned int localUdpPort;
extern char packetBuffer[255]; //buffer to hold incoming packet
//extern char ReplyBuffer[10]; // a string to send back
#endif

  

Edytowano przez _LM_
Link do komentarza
Share on other sites

Taki drobiazg:

Zamiast:

strpbrk(str, "?")

lepiej będzie:

strchr(str, '?')

A w ogóle to przecież zarówno strpbrk, jak i strchr coś tam zwracają, i może warto wykorzystać ten wynik? Poza tym w Twoim przypadku par[0] jest zawsze równe str. I tak np:

char *c;
if ((c=strchr(str,'?'))) {
  *c = 0;
  ...

eliminuje konieczność wywołania strtok.

Edytowano przez ethanak
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.