web-dev-qa-db-ja.com

Cでは、char配列にcharが存在するかどうかを確認します

文字が無効な文字のリスト/配列に属しているかどうかを確認しようとしています。

Python背景から来て、私はちょうど言うことができた:

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

通常のC char配列でこれを行うにはどうすればよいですか?

46
Amarok

同等のCコードは次のようになります。

#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;
}

Invalid_charactersはC文字列であることに注意してください。 nullで終わるchar配列。

31
RichieHindle

Cライブラリのあまり知られていないが非常に有用な(そしてC89以降の標準-「永久」を意味する)関数は、1回の呼び出しで情報を提供します。実際には、複数の機能があります-富の恥ずかしさ。これに関連するものは次のとおりです。

7.21.5.3 strcspn関数

あらすじ

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

説明

Strcspn関数は、s1が指す文字列の最大初期セグメントの長さを計算します。s1は、s2が指す文字列ではなく、文字のみで構成されています。

返品

Strcspn関数は、セグメントの長さを返します。

7.21.5.4 strpbrk関数

あらすじ

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

説明

Strpbrk関数は、s2が指す文字列から、s1が指す文字列の最初の出現箇所を特定します。

返品

Strpbrk関数は、文字へのポインター、またはs1にs2からの文字が発生しない場合はヌルポインターを返します。

質問は、「文字列の各文字について...無効な文字のリストにある場合」について尋ねます。

これらの関数を使用すると、次のことができます。

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

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

または:

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

どちらが良いかは、他に何をしたいかによって異なります。関連するstrspn()関数もありますが、これは便利な場合があります(ブラックリストではなくホワイトリスト)。

43

入力がヌルで終了する標準のC文字列であると仮定して、 strchr を使用します。

#include <string.h>

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

一方、配列がnullで終了していない場合(つまり、生データのみ)、 memchr を使用してサイズを指定する必要があります。

#include <string.h>

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

c文字列を扱う場合はstrchr関数を使用します。

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

ここにあなたがしたいことの例があります。

/* 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;
}

メモリブロックを処理するときにmemchrを使用します(nullで終わる配列ではない)

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/

5
Tom

あなたが欲しい

strchr(const char * s、int c)

文字cが文字列sにある場合、sの位置へのポインタを返します。それ以外の場合は、NULLを返します。したがって、無効な文字のリストを文字列として使用してください。

4
Keith Smith

strchr最初から文字を検索する場合(strrchr最後から):

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

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

私は元の質問が言ったと信じています:

文字が無効な文字のリスト/配列に属している

ではなく:

nullで終わる文字列に属します

もしそうなら、strchrは実際に最も適切な答えでしょう。ただし、charの配列にnull終了がない場合、またはcharがリスト構造にある場合は、nullで終了する文字列を作成してstrchrを使用するか、要素を手動で繰り返す必要があります。コレクション内で、それぞれを順番にチェックします。コレクションが小さい場合は、線形検索で問題ありません。大規模なコレクションでは、検索時間を改善するために、より適切な構造が必要になる場合があります。たとえば、ソートされた配列やバランスの取れた二分木です。

あなたの状況に最適なものを選んでください。

1
Skizz