0

可変長の文字列 (ただし、常に 100 文字未満) を受け取り、文字列に含まれるデータを個々の変数に返すプログラムを (javascript から) 変換しています。これは私のコードの最初の部分であり、明らかに、私は C とプログラミング全般に不慣れです。このコードはコードの最初のセクションのためのものですが、これを適切にコーディングする方法を学ぶことで、残りの部分をコーディングする方法を知ることができます。

私は欲しい:

  • 「stringID」として格納される最初の 4 桁
  • 「myindicator」として格納される 5 桁目
  • 「var1」として格納される 6 桁目から (インジケータ + 6) 桁

入力例:

「12345678901234567890123」

出力例:

  • 文字列 ID = 1234
  • マイインジケーター = 5
  • var1 = 67890123456

プログラムを実行すると、'String ID: H>a' が返され、プログラムがクラッシュします。どんな助けでも大歓迎です。いいえ、これは宿題ではありません。

int main()

{
char mystring[100];
char *stringID;
int nep;
int *myindicator;
char *var1;


nep = 0;
printf("Please enter your CODE\n");
scanf("%s", &mystring);

stringID = (char *)malloc(4 * sizeof(char));

if(NULL != stringID)
{

    strncpy(stringID, mystring, 4);
    stringID[4] = '\0';
    free(stringID);
    nep = nep +4;
    printf("stringID: %s\n",myindicator);
}


if(NULL != myindicator)
{
    strncpy(myindicator, (mystring+nep, 1);
    nep++; 
    myindicator = *myindicator - '0';
    printf("Indicator : %d\n",myindicator);
}

var1 = (char *)malloc((nep + 6) * sizeof(char));
if(NULL != var1)
{
    strncpy(var1, mystring+nep, (myindicator+nep+6));
    var1[myindicator+nep+6] = '\0';
    free(var1);

    printf("Var 1: %s", var1);

    nep = nep +myindicator+6;
}

getchar();
return 0;
}
4

2 に答える 2

1

私は何かを修正しました。コメントで見つけてください。でもC言語のマニュアルは要チェック…!

int main()
{
   char mystring[100];
   char *stringID;
   int nep;
   // Changed to integer, not pointer to int.
   int myindicator;
   char *var1;

   nep = 0;
   printf("Please enter your CODE\n");

   /*
       This scanf is a bad idea for the same reason for which, below, we take
       care to allocate memory enough for whatever we have to do.
       Should someone input 250 characters in a buffer of size 100, those 150
       extra characters would wreak havoc and possibly endanger the system.
   */
   // scanf("%s", &mystring);
   fgets(mystring, sizeof(mystring)-1, stdin);
   // fgets will read at most "sizeof(mystring)-1", that is, 99 bytes,
   // from "stdin" (STanDard INput), the same as scanf. But it will halt
   // when reaching the limit given. It's up to us to give a "real" limit
   // (nothing stops you from saying 15000 -- even if the true value is 100).

   // C strings are made of characters, terminated by a zero byte.
   // So you need 5 here, to store 4 characters
   stringID = (char *)malloc(5 * sizeof(char));

   if (NULL == stringID)
   {
       // Serious out of memory error: no sense going on.
       // fprintf(stderr, "Out of memory\n");
       abort();
   }

   strncpy(stringID, mystring, 4);
   stringID[4] = '\0';

   printf("ID: %s\n", stringID);

   free(stringID);

   nep = nep + 4;
   printf("NEP: %d\n", nep);

   // Now we want to decode the fifth digit.

   // I use '0' as character. So if the fifth digit is '0', '0'-'0' will give 0
   // and if it is '9', '9'-'0' will give 9 (the number).
   // The trick does not work with more than one digit, of course.
   myindicator = mystring[nep] - '0';

   // Had I wanted to read 3 digits, I would have had to copy them into a 
   // temporary buffer, add a zero in the fourth position, then run atol()
   // on the resulting buffer: atol("12345\0" /* A STRING */) = 12345 /* A NUMBER */;

   printf("VLI : %d\n", myindicator);

   // Copy "myindicator" bytes, so alloc myindicator+1 chars
   var1 = (char *)malloc((myindicator + 1) * sizeof(char));

   // Check that var1 is not null and abort if it is
   if (NULL == var1)
        abort();

   strncpy(var1, mystring + 6, myindicator);
   var1[myindicator+1] = '\0';

   // Moved this printf before the free. See why below.
   printf("Prefix : %s\n", var1);

   // NEVER use a variable after you freed it!!!
   // it might APPEAR to work, but will stab you in the back the first chance it gets.
   // Good if paranoid habit: null a var as soon as you've freed it.
   free(var1); var1 = NULL;

   getchar(); 
   return 0;
}
于 2012-07-10T20:41:25.720 に答える
0

なぜ配列を解放するのですか? それらをヒープから解放した後、それらを参照しています。

コードは次の場所でセグメンテーション違反を起こします:

  1. どこに割り当てましたmyindicatorか?

    strncpy(myindicator, (mystring+nep, 1); // ここで segfault します。

  2. 無料 (var1);

    printf("プレフィックス: %s", var1); // 再びセグメンテーション違反

  3. ここでもまた

    strncpy(var1, mystring+nep, (myindicator+nep+6)) // mystring はどこですか?

  4. 文字列入力を取得するのscanf()は恐ろしい恐ろしい考えです。のようなバッファリングされた IO を使用しますfgets()

  5. mystringバッファオーバーフローにさらされています。ユーザーが 120 バイトの文字列を入力するのを妨げているのは誰ですか? 悪意のあるコードへの慎重なジャンプ命令でスタックを書き込むことができます。

于 2012-07-10T20:41:30.533 に答える