1

私はハードウェアの割り当てを行っており、教授はこのコードを使用してプログラムをテストしています。

int main()
{
   const int SZ1 = 10;
   const int SZ2 = 7;
   const int SZ3 = 5;
   float array1[SZ1];
   float array2[SZ2];
   float array3[SZ3];

   DisplayValues(SortValues(GetValues(array1, SZ1), SZ1), SZ1);
   DisplayValues(SortValues(GetValues(array2, SZ2), SZ2), SZ2);
   DisplayValues(SortValues(GetValues(array3, SZ3), SZ3), SZ3);

   return EXIT_SUCCESS;
}

float *DisplayValues(float *p, size_t n)
{
   float previous = *p, *ptr, *end = p + n;

   setiosflags(ios_base::fixed);
   for (ptr = p; ptr < end; ++ptr)  // get each element
   {
      cout << *ptr << '\n';
      if (ptr != p)                 // if not first element...
      {
         if (previous < *ptr)       // ...check sort order
         {
            cerr << "Error - Array sorted incorrectly\n";
            return NULL;
         }
      }
      previous = *ptr;              // save this element
   }
   resetiosflags(ios_base::fixed);

   return p;
}
#endif

私が使う

float *GetValues(float *p, size_t n) 
{   
    float input;
    float *start = p;

    cout << "Enter " << n << " float values separated by whitespace: \n";

    while (scanf("%f", &input) == 1) {
        *p++ = input;
    }
    return start;
}

彼が指示したように端末ウィンドウから入力を取得し、ctrl + d を使用して EOF 文字を入力し、DisplayValues(SortValues(GetValues(GetValues(array1, SZ1), SZ1), SZ1) への最初の呼び出しを行います。ただし、 DisplayValues(SortValues(GetValues(array2, SZ2), SZ2), SZ2); の場合、プログラムの残りの部分は値を再度入力させずに終了します。と呼ばれます。これには理由または回避策がありますか? ありがとう。

4

2 に答える 2

4

CTRLD文字 (16 進数の 04) は、それ自体がファイルの終わりの文字ではありません。そのキーシーケンスを押すと、これが入力ストリームの終わりであり、そのストリームからのそれ以降の読み取りは、「ファイル」が終了したかのように扱われることを端末ドライバーに通知します。stty実際、UNIX ではコマンドを使用して、これに使用される文字を変更できます。

そのシーケンスを押すと何が起こるかというと、それ以上の入力はプログラムに与えられません。データを区切るには、よりインテリジェントなシーケンスを見つける必要があります (改行 (0x10) など)。

ただし、これにはフロートではなく文字列を入力する必要があります (空の行をチェックしたfgets、文字列を取得しsscanfてフロートを抽出するために使用できます)。

もう 1 つの可能性は、-1 を特別なセンチネル値として使用することです (-1 が有効な入力ではないと仮定します)。

私の提案はfgets/sscanfルートに行くことですが、nフロートを取得する必要があるため、次のGetValuesようにする必要があります。

float *GetValues (float *p, size_t n) {   
    float input;
    float *start = p;
    cout << "Enter " << n << " float values separated by whitespace: \n";
    while (scanf("%f", &input) == 1) {
        *p++ = input;
        if (--n >= 0)
            break;
    }
    return start;
}

制限に達すると、値の取得が停止します。完璧ではないことに注意してください。これは宿題であるため、少なくとも 1 つの問題を残しました (入力データによっては、決してそれを打てない場合があります)。

coutまた、C++ と CI/O のセマンティクス (と)を混在させるのは少し珍しいことscanfです。どちらかを選択する必要があります。これが C++ の割り当てである場合は、C++ の方が I/O を行う方法が豊富であることがわかります。C の場合coutは、コード内に場所がないため、おそらく を使用する必要がありますprintf。うまくいかないと言っているわけではありませんがそれは異常な組み合わせです.

于 2010-02-21T07:44:34.093 に答える