2017-04-24 3 views
0

私はいくつかのC++をブラッシングしているので、解決しようとしている問題の1つは文字ポインタの文字を数え、しかし私の解決策では、私は特有の結果に気付きました。私はcharへの参照を関数に渡し、それは3のカウントを返しました。なぜ、参照テストは文字への参照のために3のカウントを返すのですか?文字ポインタの文字数をカウントする

文字にヌルターミネーターがないことを認識しているので、コードはカウントし続けますが、最終的には結果が返されるため、ソリューションが不足しています。より強固なアイデアはありますか?ここに私の解決策と結果があります。

CountCharacters.cpp

#include <cstdio> 
#include <iostream> 

#define ASSERT_EQUALS(paramx1, paramx2) \ 
{\ 
     int param1 = paramx1;\ 
     int param2 = paramx2;\ 
     if (param1==param2)\ 
       std::cout << "PASS! param1=" << param1 << " param2=" << param2 << std::endl;\ 
     else\ 
       std::cout << "FAIL! param1=" << param1 << " param2=" << param2 << std::endl;\ 
} 

int countCharacters(const char * characters); 


int main() 
{ 
     char character = '1'; 
     ASSERT_EQUALS(countCharacters("string8\0"), 7); 
     ASSERT_EQUALS(countCharacters("\0"), 0); 
     ASSERT_EQUALS(countCharacters(""), 0); 
     ASSERT_EQUALS(countCharacters(NULL), 0); 
     ASSERT_EQUALS(countCharacters(&character), 1); 
     ASSERT_EQUALS(countCharacters('\0'), 0); 
     return 0; 
} 


int countCharacters(const char * characters) 
{ 
     if (!characters) return 0; 
     int count = 0; 
     const char * mySpot = characters; 
     while (*(mySpot) != '\0') 
     { 
       std::cout << "Count=" << count << " mySpot=" << *(mySpot) << std::endl; 
       count++; 
       mySpot++; 

     } 
     return count; 
} 

結果:

PASS! param1=7 param2=7 
PASS! param1=0 param2=0 
PASS! param1=0 param2=0 
PASS! param1=0 param2=0 
FAIL! param1=2 param2=1 
PASS! param1=0 param2=0 
+0

再発明したい車輪の数はいくつですか? codereviewのためのサイトがあります。 –

+1

[単一文字のStrlen関数の動作]の可能な複製](http://stackoverflow.com/questions/35477662/strlen-function-behavior-on-single-character) –

+0

あなたはあなたのcountCharactersを適合させることはできませんこのシナリオに対して機能します。ヌルで終了する文字列か単一の文字が与えられているかどうかを判断する方法はありません。私はあなたがこれを行うことを決めた場合、char *関数をオーバーロードして1を返すことをお勧めします。 – Squidy

答えて

1

あなたは文字への参照を渡していません。あなたはポインタを渡しています。具体的には、これはポインタです:

&character 

のC++を学習するとき&と*シンボルは少し混乱しています。

char character = '1';    // <- char variable 
char* characterPtr = &character; // <- pointer to the char variable 
char& characterRef = *characterPtr; // <- reference to the char variable 

だから、あなたは文字へのポインタを渡しているとあなたの関数は、文字列の頭のようにそれを処理していると、それまでの文字を数える:自分の位置場所に応じて、彼らはポインタまたは参照をすることができnullptrにヒットします。ちょうど少数のキャラクターが離れてしまったので、値2を得ているのです。

EDIT:C/C++には文字列型がありません。だからあなたは文字列の頭のような文字を扱うためにあなたが含むようなライブラリが必要です。慣習は、nullptrが文字列を終了するというものです。だから、その大会をうまくやっているだけでなく、文字へのポインタと文字列の先頭の文字へのポインタとの間に違いがないという事実を実証しているので、誤って文字へのポインタを文字列が必要な関数。関数があなたがそのメモリを割り当てたと仮定しているので、関数が文字列を '文字列'にコピーし始めるのは本当に面白いですが、他のデータが押しつぶされる可能性があります。

危険なこととは別に、文字列を使用することのもう一つの大きな欠点は、ネイティブ関数がないため、操作が面倒だということです。だから、STLのような素晴らしいライブラリは、これらの問題を解決するために書かれています。彼らはポインタを必要としないので、使用するのがずっと安全です(参照を代わりに使用し、境界チェックを行うことができます)。メソッドには多くの方法が組み込まれているため、必要なコーディング量を削減できます。

+0

ああ...わかりましたので、その場合は未定義の動作になります。どのように私はそれから自分自身を守るだろうか? – nndhawan

+0

これはニットですが、これは未定義の動作ではありません。課題は、C/C++にネイティブ文字列型がないことです。むしろ、一連の文字へのポインタを使用します。ポインタは素晴らしいものと危険なものなので、控えめに使用する必要があります。あなたの質問への短い答え:std :: stringを使用してください。 – buttonsrtoys

+0

Ok @ボタン。だから私がインタビューでこの解決策を与えたならば、この答えは十分であり、関数シグネチャが与えられれば5番目のケースを解決できないものとして無視することができます。 – nndhawan

関連する問題