4

から文字列をコピーしたいのですargv[0]が、のサイズを取得する方法がわかりませんargv[0]

これを行う方法?

int main(int argc, char* argv[])
{
  char str[20];
  if(argc>0)
      memcpy(str, argv[0], sizeof(argv[0]));
}
4

8 に答える 8

5

argv[0]は文字列なので、を使用しますstrlen

#include <string.h>

size_t length = strlen (argv[0]) + 1;

memcpy (str, argv[0], length);

ちなみに、文字列strcpyに適した、を使用することもできます。

#include <string.h>

strcpy (str, argv[0]);

strいずれの場合も、コピーがオーバーフローしないようにするには、のサイズが十分かどうかを確認する必要があります。

if (sizeof str >= length)
{
  /* Do the copy. */
}
else
{
  /* Report an error, or use dynamic allocation. */
}
于 2013-03-27T13:12:14.033 に答える
1

strdup()プラットフォームがサポートしている場合に使用できます。これにより、コードがよりシンプルになります

int main(int argc, char* argv[])
{
  char *str = NULL;
  if(argc>0) {
      str = strdup(argv[0]);
  }

  .......
  // when the str became useless then free it
  free(str);
  ........
}
于 2013-03-27T14:34:13.303 に答える
0

char* argv[]はポインタの配列(char*)なので、sizeof(argv[0])は。に等しくなりsizeof(char*)ます。

次のいずれかを使用できますstrlen

memcpy(str, argv[0], strlen(argv[0]) + 1);  // +1 because of '\0' at the end

またはさらに良いあなたが使用することができますstrcpy

strcpy(str, argv[0]);

ただし、の長さはargv[0]宛先バッファのサイズ()よりも大きい場合があるため、コピーする前にstrのサイズを確認する必要があることに注意してください。argv[0]

指定した量の文字のみをコピーすることもできますstrcnpyが、その場合は\0、の最初の20文字がない場合はargv[0]、文字列を明示的に終了する必要があるため、十分に注意してください。

于 2013-03-27T13:12:08.290 に答える
0

を使用する必要がありますstrlen。を使用する場合はsizeof、のサイズを取得しますchar*

文字列をコピーするには、を使用するstrcpyか、別のに割り当てる必要がありますchar*。さらに良いことstrncpyに、バッファがにオーバーフローするのを防ぐために、サイズ(宛先のサイズ-1)と組み合わせて使用​​しstrます。-1は、ヌル終了文字(\0)を説明するためのものです。このキャラクターを忘れないでください!strlenが20を返す場合、問題が発生します。その後、を削除し\0ます。また、strcpyの安全な使用法についても読む必要があります。また、 strncpyについて詳しくはこちらをご覧ください。

または、あなたはこれを行うことができ、それは私が言ったすべてを無意味にします:

const char* arg1 = argv[0];

この場合、これはstrlen無意味になります。

于 2013-03-27T13:13:14.307 に答える
0

Cxxが>=C99の場合

あなたがこのようにそれをすることができるより:

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

    int len = (argc>0) ? strlen(argv[0]) : 0;

    char str[len+1];
    if (argc>0)
        memcpy(str, argv[0], len+1);
}
于 2013-03-27T13:49:18.023 に答える
0

ポインタを使用し、次の長さに応じてメモリを割り当てることをお勧めしますargv[0]

int main(int argc, char* argv[])
{
  char *str = NULL;
  if(argc>0) {
      int len = strlen(argv[0])
      str = malloc((len+1)  * sizeof(char))
      memcpy(str, argv[0], (len+1));
  }

  .......
  // when the str became useless then free it
  free(str);
  ........
}
于 2013-03-27T14:32:49.327 に答える
0

要約すると、ここには多くの混乱と悪いアドバイスがあるためです。

最も狭い意味でのあなたの質問への答えは、を使用して文字列の長さを見つけることができるということですstrlensizeofデータ型のサイズをバイト単位で返します。これは、の文字​​列のchar*場合、(一般的な最新のマシンでは)4( 32ビットシステム)または8(64ビットシステムの場合)(文字列の長さに関係なく)、ただし..。

  1. これが最初に行う必要があることであることを確認してください。文字列を変更するつもりがない場合は、それをコピーする理由はありません。argv文字列は変更可能であるため(標準に従って)、変更する場合は、古い値も保持する場合にのみコピーする必要があります。

    変更するつもりがないか、古い値は必要ないが、何らかの理由(おそらく読みやすさ)で別の変数が必要な場合は、その変数を配列ではなくポインターとして宣言し、に割り当てる必要があります。それ:

    char *str = argv[0];
    
  2. 文字列をコピーすることが確実な場合は、これを使用しないmemcpyでください。を使用する必要があり、新しい文字列がを保持するのに十分な大きさであることを確認する必要がありstrcpyます。C99を使用している場合は、これを簡単に行うことができます。argv[0]

    char str[strlen(argv[0]) + 1];
    strcpy(str, argv[0]);
    

    古い標準を使用している場合は、メモリを動的に割り当てる必要があります。

    char *str = malloc(strlen(argv[0]) + 1);
    strcpy(str, argv[0]);
    

    POSIXシステムを使用している場合は、次を使用して短縮できますstrdup

    char *str = strdup(argv[0]);
    

    mallocまたはを使用している場合はstrdup、使い終わったら手動でメモリを解放する必要があることに注意してください。

    argc > 0(ちなみに、いずれの場合もチェックする必要はありません。標準でargv[0]は、プログラム名または長さゼロの文字列(つまり、)のいずれかであることがargv[0][0]保証されています'\0'。)

  3. 固定長のバッファの使用から逃れることができない場合は、結果の文字列を手動nul-terminateすることを忘れないでください。また、バッファより長い場合は文字列が切り捨てられることが許容されます。strncpy

    char str[20];
    strncpy(str, argv[0], 20); /* or 19, it doesn't matter. */
    str[19] = '\0';
    

それがすべてだと思います。

于 2013-03-27T14:47:37.040 に答える
0

ここにはそのような悪いアドバイスが殺到しています。理由はわかりません。この質問は複雑なロケット科学ではなく、初心者レベルのプログラミングです。

argv [0]に引数があることを確認しますが、正式には常に少なくとも1つの引数がmainに渡されます。argc> 0に対するチェックは防御的なプログラミングと見なされますが、余分なエラーチェックは決して悪いことではありません。

不明なバッファの内容をコピーする前に、バッファオーバーフローをチェックする必要があります。

#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  if(argc == 0)
  {
    // unexpected error
  }

  size_t len = strlen(argv[0]);
  char* str =  malloc(len * sizeof(char) + 1);
  if(str == NULL)
  {
    // no memory, error
  } 

  strcpy(str, argv[0], len);

  ...

  free(str);
}

以上です。


  • strdupはC標準ではないため、移植性がないため、悪いアドバイスです。また、完全に不要な機能です。
  • strncpyは悪いアドバイスであり、strcpyの安全なバージョンとして意図されたものではありません。これは、恐竜UNIXシステムでレコードを処理するための古いレガシー関数です。nullの終了を忘れやすいため、strcpyよりもはるかに危険です。最新のCプログラムでstrncpyを使用する理由はありません。なんらかの理由で不明ですが、バッファオーバーフローに対するガードとしてstrncpyを使用するように洗脳されたプログラマーがたくさんいます。これを行わないでください。正しい方法は、strcpy/memcpyを使用する前にバッファーが十分に大きいことを確認することです。
于 2013-03-28T07:52:03.353 に答える