2017-09-14 15 views
0

私はC/C++をかなり新しくしており、コマンドライン引数を学習しています。 strcpyを使ってコマンドライン引数をソートしようとしていますが、それは私に悪い出力を与えています。例: strcpyを使用してコマンドライン引数をソートできない


I/P:私は午前


O/P:AMI 私は

誰も私がここで間違ってやっているものに私を助けることができますか?注意:私はこのプログラムをargc = 3のみで実行しています。上記の例に記載されているように、このコードは入力用に実行されています(ソートされます)。 私はデバッグのためにループを削除しました。

#include "iostream" 
#include "cstdlib" 
#include "cstring" 
using namespace std; 

int main (int argc, char **argv) 
{ 

    char temp[100]; 

    //sorting my command line arguments 
    if(strcmp(argv[1],argv[2])>0) 
    { 
     strcpy(temp,argv[1]); 
     strcpy(argv[1],argv[2]); 
     strcpy(argv[2],temp); 
    } 

    cout<<argv[1]<<endl; 
    cout<<argv[2]<<endl; 

    return 0; 
} 
+0

コマンドライン引数のサイズは自動的に変更されないので、それらが同じ長さにならない限り、それらをコピーすることはできません。 – Galik

+0

@CroCo最初に文字列を比較しています。それを基にして、私はスワップ/ソートしています。 – siddyi

+0

@ Galikどのように可変長の引数をソートできますか? – siddyi

答えて

1

メモリレイアウトを考慮してください。あなたが$ ./a.out i amを実行すると、プログラムが起動するとき、それは次のようになります。

a . o u t \0 i \0 a m \0 
^     ^ ^
argv[0]   argv[1] argv[2] 

を書き込みargv[1]にあなたのスワッピング手続きで、このように変更します:

a . o u t \0 a m \0 m \0 
^     ^ ^
argv[0]   argv[1] argv[2] 

その後argv[2]意志への書き込みこれに再び変更:

a . o u t \0 a m i \0 \0 
^     ^ ^
argv[0]   argv[1] argv[2] 

をあなたはargv[1]をプリントアウトするとき、それはヌルバイトまで読み込みますので、あなたにamiを与えます。 argv[2]は、別の開始点から読み取って、iを与えます。

Galikが指摘しているように、これはargv[1]argv[2]が何らかの自動サイズ変更バッファではないためです。彼らはメモリへのポインタです。この時点で、正確なレイアウトは言語によって正式に定義されていないことに注意してください。使用しているプラ​​ットフォームによっては、さまざまな予測できない動作が発生する可能性があります。

この問題を解決するには、文字列の値ではなくポインタをソートしてスワップする文字列へのポインタの配列を作成する必要があります。これは、より速く(コピーするのに必要なバイト数がより少なくて済む)、安全性が高くなります(入力が100文字を超えると、現在のコードで起こるように、誤ってバッファをオーバーフローさせる方法が少なくなります)。

+0

ありがとう、これは間違いなくこれをクリアしました。編集:なぜこの答えがdownvoted理解していない。私はあなたの答えを受け入れました。 – siddyi

+2

なぜこれがダウン投票されたのか聞いてもよろしいですか? – user3553031

関連する問題