2009-05-06 8 views
0

データを入力しているテキストファイルがありますが、それを正しく取得できないようです。私は、テキストファイルをロードし、データを配置する必要があります。ここC++、getおよび>>をifstreamに使用

Michael Davidson  153 Summer Avenue  Evanston  CO 80303 
Ingrid  Johnson  2075 Woodland Road  Aurora   IL 60507 

コードされています

は、ここで(これらは本当の人々が心配しないではありません)の例として、テキストファイルから2行です構造体に変換します。私はまだC++には新しく(明らかに)、getと>>を一緒に使用するのは苦労しています。私が下にあるコードは、「状態」に到達して何かが間違ってしまうまでうまく動作します。助けてくれてありがとう!

//constants 
const int FIRST_NAME_LEN = 11; 
const int LAST_NAME_LEN = 13; 
const int ADDRESS = 25; 
const int CITY_NAME_LEN = 16; 
const int STATE_LEN = 3; 

//define struct data types 
struct CustomerType { 
    char firstName[FIRST_NAME_LEN]; 
    char lastName[LAST_NAME_LEN]; 
    char streetAddress[ADDRESS]; 
    char city[CITY_NAME_LEN]; 
    char state[STATE_LEN]; 
    int zipCode; 
}; 

//prototype function 
ifstream& getInfo(CustomerType& CT_Struct, ifstream& infile); 

int main() { 

    //declare struct objects 
    CustomerType CT_Struct; 

    ifstream infile("PGM951_customers.txt"); 
    if(!infile) { 
     cerr << "Could not open the input file." << endl; 
     exit(1); //terminates the program 
    } 

//call the function 
getInfo(CT_Struct, infile); 

return 0; 
} 

ifstream& getInfo(CustomerType& CT_Struct, ifstream& infile) { 

    while(infile) { 
     infile.get(CT_Struct.firstName, sizeof(CT_Struct.firstName)); 
     infile.get(CT_Struct.lastName, sizeof(CT_Struct.lastName)); 
     infile.get(CT_Struct.streetAddress, sizeof(CT_Struct.streetAddress)); 
     infile.get(CT_Struct.city, sizeof(CT_Struct.city)); 
     infile.get(CT_Struct.state, sizeof(CT_Struct.state)); 
     infile >> ws; 
     infile >> CT_Struct.zipCode;  

     cout << CT_Struct.firstName << " | " << CT_Struct.lastName << " | " << CT_Struct.streetAddress 
      << " | " << CT_Struct.city << " | " << CT_Struct.state << " | " << CT_Struct.zipCode << endl; 
    } 

return infile; 

} 

===編集=========== 8文字の状態で読書は私をいじりした後、私は申し訳ありません...戻ってそれを変更するのを忘れました。

+0

「これらは実際の人ではありません。心配しないでください」 これらの人は異なると頼みます:http://en.wikipedia.org/wiki/Michael_Davidson;) –

+0

しかし、彼の意見は彼が実際ではないので重要ではありません。 ;) – jalf

+0

あなたは "何がうまくいかない"と言わないでください!そこには状態がありますが、ジップはクラッシュする、または状態が間違っていますか? – crashmstr

答えて

0

もし私があなただったら私は最初からやり直すでしょう。私は希望:あなたのデータの代わりに文字配列の

  • 使用のstd ::文字列が
  • はにstringstream
  • を使用して線を解析するのstd :: getlineの
  • を使用して、ファイルから一度に行を読み込み、フォーマットされ、フォーマットされていない入力を混合避けること
+0

これは難しい理由は、名前が3,4、または5の単語を持つことがあるということです。通りの名前と都市も同様に変化します。 – dicroce

+0

私はこれが質問者が入力データを管理する学習練習であると仮定しました。そうでない場合は、XMLやCSVなどの形式を入力用に調査する必要があります。 –

+0

これを行うには、固定サイズのフィールド形式を使用するのが一番簡単な方法です。フィールド区切り文字を使用する場合は、フィールド内のフィールド区切り文字をエスケープするか、またはサイズをフォーマットにエンコードするか、XMLのような重量の重いフォーマットを使用することを心配する必要があります。 –

0

これに対する私のアプローチは、次のようになります。それぞれの行を読む)

1をI nはNULL終了バッファです。 2)書く必要があるsplit()関数を使用します。この関数は、入力として文字列を取り、リストを返さなければなりません。セパレータも必要です。この場合のセパレータは ''です。 3)リストを慎重に繰り返します(ミドルネームはありませんか?)1ワードまたは3ワードのストリートネームはどうですか?これらの列の多くは実際には単語の数が変わり、ホワイトスペース以外の分離符はないので、これはかなり難しい作業です。あなたが中間の名前を持っていないなら、最初の2つの列が名字であると仮定することができます。あなたは最後の2つが何であるかを知っています。それらの間のすべてを単一のアドレスフィールドに割り当てることができます。

3

streetAddressのスペースには、istream::get()のブレークがあります。

一つの方法は、トークンの数に応じて、その後、stringsvectorと、言うに最初の入力行をトークン化することは、あなたのCustomerTypeの適切なフィールドにこれらを変換:

vector<string> tokenize(string& line, char delim=' ') { 
     vector<string> tokens; 
     size_t spos = 0, epos = string::npos; 
     while ((epos = line.find_first_of(delim)) != string::npos) { 
      tokens.push_back(line.substr(spos, epos - spos)); 
      spos = epos; 
     } 
     return tokens;  
} 

私はストリームというだろうCustomerTypeの抽出演算子:

struct CustomerType { 
    friend istream& operator>>(istream& i, CustomerType& c); 
    string firstName, lastName, ...; 
    // ... 
}; 

istream& operator>>(istream& i, CustomerType& c) {  
    i >> c.firstName >> c.lastName; 
    string s1, s2, s3; 
    i >> s1 >> s2 >> s3; 
    c.streetAddress = s1 + s2 + s3; 
    i >> c.city >> c.state >> c.zipCode; 
    return i; 
} 
+0

私はそれが一般的にもっと激しいことに同意しますが、オペレータのオーバーロードが貧弱な人をすぐに提示したいのですか? :-) –

+0

これは私が示唆しているものです。私が考えることができるのは、アドレスフィールドに項目の数が変わる可能性があるということだけですが、そうであれば、フィールドを分割するために別の文字が必要になります(タブまたは|私のアイデアとなります)。別のセパレータでget()を実行します:) – workmad3

+0

私は、count、end of line、または区切り文字(指定されていない)まで取得すると考えていたので、空白で区切られません。 – crashmstr

1

あなたはすべてのあなたの郵便番号を含み、そして、あなたのフィールドよりも大きくなっている状態、のために8つの文字を取得しています。

infile >> skipws >> CT_Struct.firstName 
     >> CT_Struct.lastName 
     >> ... ; 

(更新:またskipws演算子を使用したくているはずだ

。それは私がメモリからこれは正しい近似より密接であることを行うために何を得るのです。)

関連する問題