web-dev-qa-db-ja.com

C ++文字配列と文字配列の比較

文字配列を次のような文字列と比較しようとしています:

const char *var1 = " ";
var1 = getenv("myEnvVar");

if(var1 == "dev")
{
   // do stuff
}

このifステートメントは決してtrueとして検証されません... var1を出力すると「dev」であり、nullで終了する文字列と関係があるのではないかと考えていましたが、「dev」とvar1のstrlenは等しい... Iまた、おそらくvar1 == "dev"は "dev"を値ではなくvar1のメモリ位置と比較していると考えられていました。 * var1 == "dev"はエラーになります。..多くのことを試みましたが、おそらくsaavy c ++開発者向けの簡単な解決策です(しばらくの間c ++をコーディングしていません)。

編集:私たちは試しました

if(strcmp(var1, "dev") == 0)

そして

if(strncmp(var1, "dev", 3) == 0)

ありがとう

編集:自宅でテストした後、同僚がデータ型を文字列に変更することを提案します。彼は大きなサイズの文字配列を文字列と比較していたと思います。 sizeof、strlenなどを出力するプログラムを作成して、作業を支援します。助けてくれてありがとう。

36
Chris Klepeis

strcmp() を使用して、文字列の内容を比較します。

_if (strcmp(var1, "dev") == 0) {
}
_

説明:Cでは、文字列はバイトを含むメモリ位置へのポインタです。等しい演算子を使用して_char*_を_char*_と比較することは、メモリーの場所を比較しているためバイトの内容ではなく、文字列の。 strcmp()などの関数は、両方の文字列を反復処理し、バイトが等しいかどうかを確認します。 strcmp()は、等しい場合は0を返し、異なる場合はゼロ以外の値を返します。詳細については、 manpage を参照してください。

65
John Millikin

文字列を使用していません。ポインターを使用しています。 _var1_は文字ポインター(_const char*_)です。文字列ではありません。 NULLで終了する場合、特定のC関数はtreat文字列として処理されますが、基本的には単なるポインタになります。

したがって、これをchar配列と比較すると、配列もポインターに減衰し、コンパイラーはoperator == (const char*, const char*)を見つけようとします。

そのような演算子は存在します。 2つのポインターを受け取り、同じアドレスを指している場合はtrueを返します。そのため、コンパイラがそれを呼び出し、コードが壊れます。

文字列の比較を行う場合は、コンパイラにpointersではなくstringsを処理するように指示する必要があります。

これを行うCの方法は、strcmp関数を使用することです。

_strcmp(var1, "dev");
_

2つの文字列が等しいの場合、これはゼロを返します。 (左側が辞書式に右側よりも大きい場合はゼロより大きい値を返し、そうでない場合はゼロより小さい値を返します。)

したがって、平等を比較するには、次のいずれかを実行する必要があります。

_if (!strcmp(var1, "dev")){...}
if (strcmp(var1, "dev") == 0) {...}
_

ただし、C++には非常に便利なstringクラスがあります。コードを使用すると、コードがかなり簡単になります。もちろん、両方の引数から文字列を作成できますが、必要なのはどちらか一方のみです。

_std::string var1 = getenv("myEnvVar");

if(var1 == "dev")
{
   // do stuff
}
_

コンパイラは、文字列と文字ポインタの比較に遭遇しました。文字ポインタを文字列に暗黙的に変換して、文字列と文字列の比較を行うことができるため、それを処理できます。そして、それらは期待どおりに動作します。

19
jalf

このコードでは、文字列値を比較するのではなく、ポインター値を比較しています。文字列値を比較する場合は、strcmpなどの文字列比較関数を使用する必要があります。

if ( 0 == strcmp(var1, "dev")) {
  ..
}
1
JaredPar

より安定した機能があり、文字列の折り畳みも取り除きます。

// Add to C++ source
bool string_equal (const char* arg0, const char* arg1)
{
    /*
     * This function wraps string comparison with string pointers
     * (and also works around 'string folding', as I said).
     * Converts pointers to std::string
     * for make use of string equality operator (==).
     * Parameters use 'const' for prevent possible object corruption.
     */
    std::string var0 = (std::string) arg0;
    std::string var1 = (std::string) arg1;
    if (var0 == var1)
    {
        return true;
    }
    else
    {
        return false;
    }
}

そして、ヘッダーに宣言を追加します

// Parameters use 'const' for prevent possible object corruption.
bool string_equal (const char* arg0, const char* arg1);

使用するには、if(またはternary)ステートメント/ブロックの条件として 'string_equal'呼び出しを配置するだけです。

if (string_equal (var1, "dev"))
{
    // It is equal, do what needed here.
}
else
{
    // It is not equal, do what needed here (optional).
}

ソース:sinatramultimedia/fl32 codec(自分で作成)

0

「dev」はstringではなく、const char *のようなvar1です。したがって、実際にメモリアドレスを比較しています。 var1は文字ポインターであるため、*var1は単一の文字(正確にはポイントされた文字シーケンスの最初の文字)です。 charをcharポインタと比較することはできません。これが機能しなかった理由です。

これはc ++としてタグ付けされているため、charポインターの代わりにstd::stringを使用するのが賢明です。これにより、==が期待どおりに機能します。 (const std::string var1の代わりにconst char *var1を実行するだけです。

0
sepp2k

以下のこのプログラムについてのあなたの考え

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

int main ()
{
char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
int n;
puts ("Looking for R2 astromech droids...");
for (n=0 ; n<3 ; n++)
if (strncmp (str[n],"R2xx",2) == 0)
{
  printf ("found %s\n",str[n]);
}
return 0;
}
//outputs:
//
//Looking for R2 astromech droids...
//found R2D2
//found R2A6

配列に何かを入力し、上記のプログラムのようなstrcmp関数を使用することを検討する必要がある場合...変更されたプログラムを以下で確認してください

#include <iostream>
#include<cctype>
#include <string.h>
#include <string>
using namespace std;

int main()
{
int Students=2;
int Projects=3, Avg2=0, Sum2=0, SumT2=0, AvgT2=0, i=0, j=0;
int Grades[Students][Projects];

for(int j=0; j<=Projects-1; j++){
  for(int i=0; i<=Students; i++) {
 cout <<"Please give grade of student "<< j <<"in project "<< i  <<  ":";
  cin >> Grades[j][i];

  }
  Sum2 = Sum2 + Grades[i][j];
     Avg2 = Sum2/Students;
}
SumT2 = SumT2 + Avg2;
AvgT2 = SumT2/Projects;
cout << "avg is  : " << AvgT2 << " and sum : " << SumT2 << ":";
return 0;
}

1つの入力のみを読み取り、残りをスローする以外は文字列に変更します。2つのforループと2つのポインターが必要になる場合があります。

#include <cstring>
#include <iostream>
#include <string>
#include <stdio.h>
using namespace std;
int main()
{
char name[100];
//string userInput[26];
int i=0, n=0, m=0;
cout<<"your name? ";
cin>>name;
cout<<"Hello "<<name<< endl;

char *ptr=name;
for (i = 0; i < 20; i++)
{
cout<<i<<" "<<ptr[i]<<" "<<(int)ptr[i]<<endl;
}   
int length = 0;
while(name[length] != '\0')
{
length++;
}
                    for(n=0; n<4; n++)
                {
                            if (strncmp(ptr, "snit", 4) == 0)
                            {
            cout << "you found the snitch "    <<        ptr[i];
                            }
                }
cout<<name <<"is"<<length<<"chars long";
}
0
101dolmations