Forum: PC-Programmierung ANSI C: Position im Text finden


von Flo (Gast)


Lesenswert?

Hallo,

folgendes Problem möchte ich lösen. Ich habe einen char Buffer dieser 
enthält einen Text. Nun soll zur Laufzeit, wenn ein bestimmtrest Wort 
vorkommt soll
ab diesem Wort danach alles mit printf ausgegeben werden.
Welche Möglichkeit gibt es da?

von Rolf M. (rmagnus)


Lesenswert?

mit strstr nach dem Wort suchen, den zurückgelieferten Zeiger für die 
Ausgabe nutzen.

von MaWin (Gast)


Lesenswert?

Flo schrieb:
> Welche Möglichkeit gibt es da?

Viele.

Suchst du eine zur Laufzeit schnelle oder eine einfach zu realisierende 
?

von PittyJ (Gast)


Lesenswert?

Flo schrieb:
> Welche Möglichkeit gibt es da?

Die einfachste Möglichkeit ist in einem Forum deiner Wahl zu betteln, 
dass dir jemand den Code schreibt.
Das funktioniert immer, und du musst nicht einmal denken.

von PittyJ (Gast)


Lesenswert?

Ansonsten kann man auch bei google
"c string functions"
eingeben, und erhält 354000000 Ergebnisse
z.B.
https://beginnersbook.com/2014/01/c-strings-string-functions/

Da müsste man dann denken.

von Flo (Gast)


Lesenswert?

Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere 
Möglichkeit?
Es wird beim Empfang von seriellen Daten eingesetzt.

von Dirk B. (dirkb2)


Lesenswert?

Flo schrieb:
> Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere
> Möglichkeit?
> Es wird beim Empfang von seriellen Daten eingesetzt.

Es ist erst Donnerstag.
Den einen Tag hättest du noch warten können.

von mh (Gast)


Lesenswert?

Flo schrieb:
> Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere
> Möglichkeit?

Hast du dir denn vorher Gedanken gemacht, was schnell und langsam in 
diesem Fall bedeutet? Oder ist es einfach nur gefühlt langsam?

von Rolf M. (rmagnus)


Lesenswert?

Flo schrieb:
> Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere
> Möglichkeit?
> Es wird beim Empfang von seriellen Daten eingesetzt.

Dass das auf einem PC zu langsam zum Empfang von seriellen Daten ist, 
halte ich für sehr unwahrscheinlich.

von Klaus W. (mfgkw)


Lesenswert?

Flo schrieb:
> Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere
> Möglichkeit?
> Es wird beim Empfang von seriellen Daten eingesetzt.

Wahrscheinlich wartet er noch auf das fehlende r.
Oder wie sieht dein Programm aus?

von OldMan (Gast)


Lesenswert?

Klaus W. schrieb:
> Oder wie sieht dein Programm aus?

Das will niemand wirklich sehen ;-)

von Flo (Gast)


Angehängte Dateien:

Lesenswert?

Die Applikation ist in C/C++ geschrieben. Ich benutze windows.h um auf 
die relevanten Funktionen für die serielle Schnittstelle zu nutzen. In 
einem Thread wird ständig geprüft ob Daten von der seirellen 
Schnittstelle anliegen.

von PittyJ (Gast)


Lesenswert?

OldMan schrieb:
> Klaus W. schrieb:
>> Oder wie sieht dein Programm aus?
>
> Das will niemand wirklich sehen ;-)

Doch

Damit ich heute noch mal ein Lächeln im Gesicht habe.

von PittyJ (Gast)


Lesenswert?

PittyJ schrieb:
> OldMan schrieb:
>> Klaus W. schrieb:
>>> Oder wie sieht dein Programm aus?
>>
>> Das will niemand wirklich sehen ;-)
>
> Doch
>
> Damit ich heute noch mal ein Lächeln im Gesicht habe.

Gerade den Code gesehen, es war sogar ein Lachen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

PittyJ schrieb:
> Gerade den Code gesehen, es war sogar ein Lachen.

Was hilft diese Arroganz jetzt dem TE?

Um's konkret zu machen:

* der gezeigte Code enthält keinerlei Auswertung der empfangenen 
Zeichen; aber genau um diese geht es ja eigentlich im Thread hier
* immer mal was zu lesen und dann eine ganze Sekunde warten beschwört ja 
(je nach Baudrate) Datenverluste regelrecht herbei; ich habe keine 
Ahnung vom Windows-API, aber es sollte doch irgendeine API-Methode 
geben, mit der man auf ein (oder mehrere) Zeichen warten kann, genau an 
der Stelle sollte der Thread warten
* einen Zeiger zuerst zu benutzen 
(pSeriell->LastInterruptTime=pSeriell->LastTime;) und danach zu testen, 
ob er nicht 0 ist, ist natürlich Humbug

: Bearbeitet durch Moderator
von MaWin (Gast)


Lesenswert?

Flo schrieb:
> Hab das mit strst getestet. Ist langsam. Gibt es eine schnellere
> Möglichkeit?
> Es wird beim Empfang von seriellen Daten eingesetzt.

Ah, fein, 2 weitere Salamischeiben.

Ja, üblicherweise verwendet man eine state-machine als Parser für 
Einzelzeichen, der im state sich merkt wie viele Zeichen vorher korrekt 
waren und bei erkannter Zeichenfolge ein flag setzt so dass nachfolgende 
Zeichen ausgegeben werden.

Wie viele braucht es noch bis die Salami komplett ist ?

Flo schrieb:
> Die Applikation ist in C/C++ geschrieben

Ähm, nein. Du hast irgendwas von irgendwo her kopiert ohne zu wissen was 
es tut.

von Flo (Gast)


Lesenswert?

Wenn Nachrichten eintreffen wird die Callback Funktion ausgeführt. In 
dieser Callback Funktion wird dann die Funktion RxFrame ausgeführt.
1
void RxCallback()
2
{
3
  Len = Port.pM->ReceiveFrame(&Port, RxBuffer, UART_FRAME_SIZE);
4
  if (Len )
5
  {
6
7
        }
8
}

von Funker (Gast)


Lesenswert?

MaWin schrieb:

> Wie viele braucht es noch bis die Salami komplett ist ?

42 :-)

von PittyJ (Gast)


Lesenswert?

Jörg W. schrieb:
> PittyJ schrieb:
>> Gerade den Code gesehen, es war sogar ein Lachen.
>
> Was hilft diese Arroganz jetzt dem TE?
>

Nein, die hilft ihm überhaupt nicht. Allerdings ist der Code nicht von 
ihm. Wer sich in Callbacks etc. begibt, der sollte schon mal einfache 
Stringverarbeitung kennen.
Die Stelle, wo er die Vergleich machen möchte, befindet sich nicht im 
Sourcecode, sondern müßte komplett ergänzt werden.
Das, was wir als Source sehen, ist ein Copy& Paste, ohne dass der TO 
wirklich eine Ahnung davon hat.

Ich plädiere immer dafür, erst einmal ein paar Basics zu lernen. So 
einfach mal alle Stringfunktionen. Oder auch std::string, weil die 
angenehmer sind.

Sorry: 90% Copy und Paste, die restlichen 10% aus dem Forum hier? So 
geht die Welt nicht.

von DerEgon (Gast)


Lesenswert?

Jörg W. schrieb:
> immer mal was zu lesen und dann eine ganze Sekunde warten

Sleep wartet nicht eine Sekunde, sondern eine Millisekunde.

https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep

von Flo (Gast)


Lesenswert?

Ja genau nur eine Millisekunde.

Ich bin aktuell dabei das ganze nochmals durchzugehen woran es genau 
liegen könnte. Im Prinzip werden mittels Thread geprüft ob Daten 
anliegen wenn ja sollen diese im Puffer gespeichert werden. Die Daten 
von der seriellen Schnittstelle haben eine Enderkennung "\r\n". Und ein 
gültige Nachricht beginnt immer mit einem + danach folgenden die Daten 
und zum Schluss werden zur Enderkennung die zwei Zeichen gesendet 
"\r\n".

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

DerEgon schrieb:
> Jörg W. schrieb:
>> immer mal was zu lesen und dann eine ganze Sekunde warten
>
> Sleep wartet nicht eine Sekunde, sondern eine Millisekunde.

Ah OK.

Trotzdem Mist: man wartet auf ein Ereignis und nicht stur 'ne Zeit ab.

Unter Posix würde man poll() benutzen. Was auch immer Win-API da hat, 
sollte man nehmen.

von Flo (Gast)


Lesenswert?

Der Code wo ich da habe ich echter Mist. Bin da etwas überfragt. Brauche 
eigentlich nur für einen Test eine funktionierende serielle 
Kommunikation kann auch in C# sein.

von Εrnst B. (ernst)


Lesenswert?

Flo schrieb:
> Brauche
> eigentlich nur für einen Test eine funktionierende serielle
> Kommunikation

Gegenstelle ist ein Arduino?

dann hätte ich als etwas schrägen Vorschlag:
"processing" am PC.

https://processing.org/

Diese API kommt dir dann evtl. vertraut vor:

https://processing.org/reference/libraries/serial/index.html

das ganze Graphik-Künstler-Video-Zeug was mitkommt muss man ja nicht 
nutzen.

von Flo (Gast)


Lesenswert?

Erstmal Danke Ernst,

meine Gegenstelle ist ein spezieller Chip der mit at Kommandos gesteuert 
wird.

von Stephan (Gast)


Lesenswert?

Um das also abzukürzen: du suchst also einen „AT Parser“.
Wenn Du nicht in der Lage bist, einen nach Deinen Vorstellungen zu 
entwickeln, nimm doch als Vorbild eins der ca. 42 Fantasillionen 
Beispiele: google „at parser“.

von Flo (Gast)


Lesenswert?

Was ich suche/brauche ist ein gescheite C Applikation für eine serielle 
Kommunikation.

von Stephan (Gast)


Lesenswert?

Na dann!
Frau zum Shoppen/Freundin schicken, Kanne Kaffee kochen und frisch ans 
Werk!
Morgen mittag hast Du es halbwegs am laufen…🥳
Wenn Du dann noch konkrete Fragen hast…

von Flo (Gast)


Lesenswert?

So ich bins nochmal.

Hab nun mal was eigenes aufgesetzt. Jetzt ist es aber nach wie vor so, 
dass
wenn ich zyklisch jede 100ms UART Nachrichten (pro Frame 256 bytes) 
versende die von der Gegenstelle gesendeten Nachrichten nicht sofort 
empfangen kann.

von Flo (Gast)


Lesenswert?

1
CSerial::CSerial(char* com_port, DWORD COM_BAUD_RATE)
2
{
3
  connected_ = false;
4
5
  io_handler_ = CreateFileA(static_cast<LPCSTR>(com_port),
6
    GENERIC_READ | GENERIC_WRITE,
7
    0,
8
    NULL,
9
    OPEN_EXISTING,
10
    FILE_ATTRIBUTE_NORMAL,
11
    NULL);
12
13
  if (io_handler_ == INVALID_HANDLE_VALUE) 
14
  {
15
    if (GetLastError() == ERROR_FILE_NOT_FOUND)
16
      printf("Warning: Handle was not attached. Reason: %s not available\n", com_port);
17
  }
18
  else {
19
20
    DCB dcbSerialParams = { 0 };
21
22
    if (!GetCommState(io_handler_, &dcbSerialParams)) 
23
    {
24
      printf("Warning: Failed to get current serial params");
25
    }
26
27
    else 
28
    {
29
      dcbSerialParams.BaudRate = COM_BAUD_RATE;
30
      dcbSerialParams.ByteSize = 8;
31
      dcbSerialParams.StopBits = ONESTOPBIT;
32
      dcbSerialParams.Parity = NOPARITY;
33
      dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE;
34
35
      if (!SetCommState(io_handler_, &dcbSerialParams))
36
        printf("Warning: could not set serial port params\n");
37
      else 
38
      {
39
        connected_ = true;
40
        PurgeComm(io_handler_, PURGE_RXCLEAR | PURGE_TXCLEAR);
41
      }
42
    }
43
  }
44
}
1
string CSerial::ReadSerialPort(int reply_wait_time) 
2
{
3
4
  DWORD bytes_read;
5
  char inc_msg[1];
6
  string complete_inc_msg;
7
  bool began = false;
8
9
  unsigned long start_time = time(nullptr);
10
11
  ClearCommError(io_handler_, &errors_, &status_);
12
13
  while ((time(nullptr) - start_time) < reply_wait_time) 
14
  {
15
    if (status_.cbInQue > 0) 
16
    {
17
      if (ReadFile(io_handler_, inc_msg, 1, &bytes_read, NULL)) 
18
      {
19
        began = true;
20
21
        if (inc_msg[0] == '\n')
22
          return complete_inc_msg;
23
24
        if (inc_msg[0] != '\n')
25
          complete_inc_msg.append(inc_msg, 1);
26
      }
27
      else
28
        return "Warning: Failed to receive data.\n";
29
    }
30
  }
31
  return complete_inc_msg;
32
}
1
bool CSerial::WriteSerialPort(char* data_sent)
2
{
3
  DWORD bytes_sent;
4
5
  unsigned int data_sent_length = strlen(data_sent);
6
7
  if (!WriteFile(io_handler_, (void*)data_sent, data_sent_length, &bytes_sent, NULL)) 
8
  {
9
    ClearCommError(io_handler_, &errors_, &status_);
10
    return false;
11
  }
12
  else
13
    return true;
14
}

von PittyJ (Gast)


Lesenswert?

Bist du sicher, dass du das aufgesetzt hast?
Einerseits die teilweise ordentlichen, nicht trivialen Programmteile, 
die du postest.
Andererseits das Unverständnis von Basics und mangelnde Kenntnis von 
einfachsten Stringroutinen.
Deine ersten Tests waren in C. Jetzt kommt hier C++?

Für mich sieht das mehr so aus, als dass du nur eine neue Quelle für 
Copy&Paste erschlossen hast.

von Flo (Gast)


Lesenswert?

Gibt es dazu noch Möglichkeiten dies zu optimieren?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Flo schrieb:
> Gibt es dazu noch Möglichkeiten dies zu optimieren?

Code verstehen, deinen tatsächlichen Flaschenhals finden, dann 
reparieren.

So kann dir das keiner sagen. Selbst mit 'ner UART von 1 MBaud ist ein 
heutiger PC locker in der Lage, da einige strstr()-Aufrufe auf das 
Resultat anzuwenden, ohne dass irgendwas klemmt. Wenn da bei dir was 
nicht funktioniert, liegt das also ganz sicher nicht an strstr() (oder 
ähnlichen Standardfunktionen), sondern an irgendwas ganz anderem.

Dafür müsstest du aber erstmal wissen, was du da überhaupt tust. Danach 
müsstest du analysieren, warum es bei dir zu langsam wird. Erst dann 
brauchst du drüber nachzudenken, wie man es "optimiert".

von Dirk B. (dirkb2)


Lesenswert?

Flo schrieb:
> COM_BAUD_RATE

Es wird für immer ein Rätsel bleiben.

Werden Wetten für den Wert angenommen?

von Win32-Serial-API (Gast)


Lesenswert?

Dirk B. schrieb:
> Werden Wetten für den Wert angenommen?

Irgendwas möglichst hohes. Weil das laggt sonst.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.