2012-01-07 32 views
2

ここは簡単な質問です。私はこのC++コードを書いた:バッファオーバーフローを避けるためにWidth()でC++でcinを使う

char chaine[12]; 
    cin.width(12); 
    cin >> chaine; 

をしかし、私は、実行時に12文字より一部のテキストlonguerを入力すると、Visual Studioは、スタックが今壊れていることを私に知らせます。

私はこの問題がバッファオーバーフローであることを理解しています。しかし、私は "幅"の方法はこれを防ぐだろうと思った。

誰かがバッファオーバーフローから保護していない場合、widthメソッドの機能は何ですか?私はオンラインで検索しましたが、何も見つかりませんでした。

ありがとうございます!

+1

さらにコードはありますか?これは私にとって大丈夫です。私が見ている唯一の問題は、 'chaine'がゼロ終了しないことです。後で問題を引き起こす可能性があります。 –

+2

良い方法があるのは分かりますよね? 'std :: string chaine; std :: cin >> chaine; 'バッファオーバーフローが心配する必要はありません。 – cHao

+0

それは全体のコードです: int main() { \t char chaine [12]; cin32.png \t cin >> chaine; return 0; } – Phil

答えて

3

このコードは実際には入力を11文字に限定することになっています(12文字目は終了ヌル文字に使用されます)。標準では、27.7.2.2.3 [istream :: extractors]パラグラフ7と8で明示しています。

... width()が0より大きい場合、nはwidth()です。 ...文字は、次のいずれかが発生するまで抽出され、格納されます。 - n-1文字が格納されます。 ...

明らかに11文字しか読まないgccでも試しました。私はこの問題の最良の回避策が何であるか分かりません。私は単純にstd::stringのオブジェクトを読んで、必要なだけ大きくすることができるので、通常、このような問題は発生しません。まあ、いくつかの巨大な制限もあり、これを超えると何が起こるかは決して試していません。絶対にあなた場合あなたは二つのことを行うことができchar配列に読み込む必要があります。

  1. あなたはcharアレイ用のアダプタを作成し、適切な入力演算子を定義することができ、自分自身
  2. あなたはどのフィルタリングストリームバッファを作成することができます一時的にインストールされ、文字の数を制限したり、空白文字を読み取ったりしているようです。

以下は、後者を実行する方法の例です。実際には、アダプタを作成する手法を使用して、配列のサイズに基づいて自動的に幅を設定することができます。

#include <iostream> 
#include <cctype> 

struct adaptor 
{ 
    template <int Size> 
    adaptor(char (&array)[Size]): it(array), end(array + Size - 1) {} 
    mutable char* it, * end; 
}; 

std::istream& operator>> (std::istream& in, adaptor const& value) 
{ 
    std::istreambuf_iterator<char> it(in), end; 
    if (it == end) 
    { 
     in.setstate(std::ios_base::failbit); 
    } 
    for (; it != end && value.it != value.end && !std::isspace(static_cast<unsigned char>(*it)); 
     ++it, ++value.it) 
    { 
     *value.it = *it; 
    } 
    *value.it = 0; 
    return in; 
} 

int main() 
{ 
    char buffer[12]; 
    if (std::cin >> adaptor(buffer)) 
     std::cout << "read='" << buffer << "'\n"; 
    else 
     std::cout << "input failed\n"; 
} 
関連する問題