48

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

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"はエラーになります....多くのことを試しました。おそらくsaavyc++開発者のための簡単な解決策です(私は長い間c ++をコーディングしていません)。

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

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

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

ありがとう

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

4

6 に答える 6

81

strcmp()文字列の内容を比較するために使用します。

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

説明: C では、文字列はバイトを含むメモリ位置へのポインタです。char*等値演算子を使用して aと a を比較すると、char*期待どおりに動作しません。これは、文字列のバイト コンテンツではなくメモリ位置を比較しているためです。のような関数strcmp()は、両方の文字列を反復処理し、バイトをチェックして等しいかどうかを確認します。strcmp()等しい場合は 0 を返し、異なる場合はゼロ以外の値を返します。詳細については、マンページを参照してください。

于 2009-08-25T19:52:54.733 に答える
25

あなたは文字列を扱っていません。あなたはポインタを扱っています。 var1char ポインター ( const char*) です。文字列ではありません。null で終わる場合、特定の C 関数はそれを文字列として扱いますが、基本的には単なるポインターです。

したがって、それを char 配列と比較すると、配列もポインターに減衰し、コンパイラーはoperator == (const char*, const char*).

そのようなオペレーターは存在します。2 つのポインターを取りtrue、それらが同じアドレスを指している場合は戻ります。したがって、コンパイラがそれを呼び出し、コードが壊れます。

文字列比較を行いたい場合は、ポインターではなく文字列を処理することをコンパイラーに伝える必要があります。

これを行う 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
}

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

于 2009-08-25T21:39:08.233 に答える
1

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

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

于 2009-08-25T20:00:48.463 に答える
1

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

// 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 (または三項) ステートメント/ブロックの条件として '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 コーデック (自分で書いたもの)

于 2015-09-04T17:26:31.413 に答える
1

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

if ( 0 == strcmp(var1, "dev")) {
  ..
}
于 2009-08-25T19:53:23.640 に答える
0

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

#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";
}
于 2016-10-01T13:56:48.847 に答える