In C – prüfen Sie, ob ein Zeichen in einem Zeichenarray vorhanden ist

Lesezeit: 7 Minuten

Benutzeravatar von Amarok
Amarok

Ich versuche zu überprüfen, ob ein Zeichen zu einer Liste/einem Array ungültiger Zeichen gehört.

Da ich aus einem Python-Hintergrund komme, konnte ich früher einfach sagen:

for c in string:
    if c in invalid_characters:
        #do stuff, etc

Wie kann ich das mit normalen C-Char-Arrays machen?

Benutzeravatar von Jonathan Leffler
Jonathan Leffler

Die weniger bekannten, aber äußerst nützlichen (und seit C89 Standard – was „für immer“ bedeutet) Funktionen in der C-Bibliothek liefern die Informationen in einem einzigen Aufruf. Tatsächlich gibt es mehrere Funktionen – eine Verlegenheit des Reichtums. Die dafür relevanten sind:

7.21.5.3 Die strcspn-Funktion

Zusammenfassung

#include <string.h>
size_t strcspn(const char *s1, const char *s2);

Beschreibung

Die Funktion strcspn berechnet die Länge des maximalen Anfangssegments der Zeichenfolge, auf die s1 zeigt, das vollständig aus Zeichen besteht, die nicht aus der Zeichenfolge stammen, auf die s2 zeigt.

Kehrt zurück

Die Funktion strcspn gibt die Länge des Segments zurück.

7.21.5.4 Die strpbrk-Funktion

Zusammenfassung

#include <string.h>
char *strpbrk(const char *s1, const char *s2);

Beschreibung

Die Funktion strpbrk lokalisiert das erste Vorkommen in der Zeichenfolge, auf die s1 zeigt, eines beliebigen Zeichens aus der Zeichenfolge, auf die s2 zeigt.

Kehrt zurück

Die Funktion strpbrk gibt einen Zeiger auf das Zeichen zurück oder einen Nullzeiger, wenn kein Zeichen aus s2 in s1 vorkommt.

Die Frage fragt nach “für jedes Zeichen in der Zeichenfolge … wenn es sich in der Liste der ungültigen Zeichen befindet”.

Mit diesen Funktionen können Sie schreiben:

size_t len = strlen(test);
size_t spn = strcspn(test, "invald");

if (spn != len) { ...there's a problem... }

Oder:

if (strpbrk(test, "invald") != 0) { ...there's a problem... }

Was besser ist, hängt davon ab, was Sie sonst noch tun möchten. Es gibt auch das Verwandte strspn() Funktion, die manchmal nützlich ist (Whitelist statt Blacklist).

  • erstaunlich, wie viele Leute vorgeschlagen haben strchr! strpbrk ist eindeutig die Ideallösung.

    – Evan Teran

    25. Mai 2010 um 0:37 Uhr

  • Dies sollte eigentlich die akzeptierte Antwort sein! C ist nicht ganz ohne Batterien…

    – Aqtau

    3. Oktober 2014 um 9:27 Uhr

  • In Ihrer Beschreibung von strpbrk any character from the string pointed to by s2aber in Ihrem Beispiel testen Sie gegen "invalid". Wird dadurch nicht nach einem Vorkommen eines der einzelnen Zeichen in der Zeichenfolge gesucht "invalid"?

    – Isaak Baker

    23. September 2015 um 17:27 Uhr

  • @IsaacBaker: Ich bin mir nicht sicher, was Sie fragen. Meiner Meinung nach fragt Ihre “Wird das nicht” -Frage, ob sich die Funktion wie dokumentiert verhält (die Antwort ist ja), aber ich bin sicher, Sie müssen einen Grund für die Frage gehabt haben, also muss ich Sie missverstehen fragen.

    – Jonathan Leffler

    23. September 2015 um 17:31 Uhr

  • @JonathanLeffler: Was ich zu fragen/zu sagen versuchte, ist Folgendes: Ihre Antwort scheint etwas widersprüchlich oder verwirrend zu sein. In deiner Beschreibung von strpbrk Sie haben die richtige Definition, aber in Ihrem Beispiel, if (strpbrk(test, "invalid") != 0) { ...there's a problem... }es scheint, dass Sie nach einer zusammenhängenden Zeichenkette suchen, "invalid"sondern sucht stattdessen nach dem ersten Vorkommen von irgendein enthaltenes Zeichen "invalid". Ist das wahr und richtig?

    – Isaak Baker

    20. Oktober 2015 um 15:34 Uhr


Benutzeravatar von RichieHindle
Richie Hindle

Der äquivalente C-Code sieht folgendermaßen aus:

#include <stdio.h>
#include <string.h>

// This code outputs: h is in "This is my test string"
int main(int argc, char* argv[])
{
   const char *invalid_characters = "hz";
   char *mystring = "This is my test string";
   char *c = mystring;
   while (*c)
   {
       if (strchr(invalid_characters, *c))
       {
          printf("%c is in \"%s\"\n", *c, mystring);
       }

       c++;
   }

   return 0;
}

Beachten Sie, dass invalid_characters ein C-String ist, dh. ein nullterminiertes char Reihe.

  • Der Versuch, nicht wählerisch zu sein, aber wenn es in C ist, sollten Sie std::cout nicht durch den entsprechenden Aufruf von printf() ersetzen? Oder zumindest etwas, das in C existiert?

    – Totenkopf

    1. Juli 2009 um 22:07 Uhr

  • Obwohl diese Schleife mit strchr() funktioniert, denke ich, dass es besser ist, ‘strcspn()’ zu verwenden oder strpbrk() ohne die Schleife im Benutzercode.

    – Jonathan Leffler

    1. Juli 2009 um 23:29 Uhr

  • @Jonathan: Sie haben Recht, aber ich habe den Code ähnlich dem ursprünglichen Python des OP gehalten und die Frage beantwortet: “Überprüfen Sie, ob ein Zeichen in einem Zeichenarray vorhanden ist”.

    – Richie Hindle

    1. Juli 2009 um 23:40 Uhr

  • Wäre es in dieser Situation nicht besser, die ungültigen Zeichen zu durchlaufen und zu überprüfen, ob sie in mystring (mit strchr) vorhanden sind, anstatt jedes Zeichen in mystring zu überprüfen, um festzustellen, ob es sich um ein ungültiges Zeichen handelt?

    – mk12

    15. Juli 2010 um 17:18 Uhr

  • @ mk12: Es kommt darauf an. Angenommen, Sie haben N Zeichen im Heuhaufen, die durchsucht werden, und M Zeichen in der Nadel, nach der Sie suchen. Wenn alle Zeichen im Heuhaufen gültig sind, landen Sie mit NxM-Vergleichen, wie auch immer Sie es machen. Normalerweise ist M viel kleiner als N. Wenn das erste Zeichen des Heuhaufens das letzte ungültige Zeichen in der Nadel ist, würde Ihre Suche N*(M-1) Vergleiche durchführen, während die Alternative nur M Vergleiche durchführen würde. Wenn das erste Zeichen im Heuhaufen das erste ungültige Zeichen in der Nadel ist, stoppen beide Systeme nach 1 Vergleich.

    – Jonathan Leffler

    7. März 2017 um 18:43 Uhr

Benutzeravatar von DaveR
DaveR

Angenommen, Ihre Eingabe ist eine standardmäßige nullterminierte C-Zeichenfolge, die Sie verwenden möchten strchr:

#include <string.h>

char* foo = "abcdefghijkl";
if (strchr(foo, 'a') != NULL)
{
  // do stuff
}

Wenn Ihr Array andererseits nicht nullterminiert ist (dh nur Rohdaten), müssen Sie verwenden memchr und geben Sie eine Größe an:

#include <string.h>

char foo[] = { 'a', 'b', 'c', 'd', 'e' }; // note last element isn't '\0'
if (memchr(foo, 'a', sizeof(foo)))
{
  // do stuff
}

Toms Benutzeravatar
Tom

Verwenden Sie die strchr-Funktion, wenn Sie mit C-Strings arbeiten.

const char * strchr ( const char * str, int character );

Hier ist ein Beispiel dafür, was Sie tun möchten.

/* strchr example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char invalids[] = ".@<>#";
  char * pch;
  pch=strchr(invalids,'s');//is s an invalid character?
  if (pch!=NULL)
  {
    printf ("Invalid character");
  }
  else 
  {
     printf("Valid character");
  } 
  return 0;
}

Verwenden Sie memchr beim Umgang mit Speicherblöcken (als nicht nullterminierte Arrays)

const void * memchr ( const void * ptr, int value, size_t num );

/* memchr example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char * pch;
  char invalids[] = "@<>#";
  pch = (char*) memchr (invalids, 'p', strlen(invalids));
  if (pch!=NULL)
    printf (p is an invalid character);
  else
    printf ("p valid character.\n");
  return 0;
}

http://www.cplusplus.com/reference/clibrary/cstring/memchr/

http://www.cplusplus.com/reference/clibrary/cstring/strchr/

Sie wollen

strchr (const char *s, int c)

Wenn der Charakter c ist in der Schnur s es gibt einen Zeiger auf die Position in s zurück. Andernfalls gibt es NULL zurück. Verwenden Sie also einfach Ihre Liste der ungültigen Zeichen als Zeichenfolge.

Benutzeravatar von dfa
dfa

strchr um ein Zeichen von Anfang an zu suchen (strchr ab Ende):

  char str[] = "This is a sample string";

  if (strchr(str, 'h') != NULL) {
      /* h is in str */
  }

Benutzeravatar von Tim Cooper
Tim Cooper

Ich glaube, die ursprüngliche Frage lautete:

ein Zeichen gehört zu einer Liste/einem Array ungültiger Zeichen

und nicht:

gehört zu einem nullterminierten String

was, wenn ja, dann strchr wäre in der Tat die passendste Antwort. Wenn es jedoch keine Nullterminierung für ein Array von Zeichen gibt oder wenn sich die Zeichen in einer Listenstruktur befinden, müssen Sie entweder eine nullterminierte Zeichenfolge erstellen und verwenden strchr oder manuell über die Elemente in der Sammlung iterieren und jedes der Reihe nach überprüfen. Wenn die Sammlung klein ist, ist eine lineare Suche in Ordnung. Eine große Sammlung benötigt möglicherweise eine geeignetere Struktur, um die Suchzeiten zu verbessern – beispielsweise ein sortiertes Array oder einen ausgewogenen Binärbaum.

Wählen Sie, was für Ihre Situation am besten geeignet ist.

1410170cookie-checkIn C – prüfen Sie, ob ein Zeichen in einem Zeichenarray vorhanden ist

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy