これは私が読む必要があるファイルです。
Coca-Cola,0.75,20
Root Beer,0.75,20
Sprite,0.75,20
Spring Water,0.80,20
Apple Juice,0.95,20
これをそれぞれ変数にする必要があります。たとえば、drinkName、drinkCost、drinkQuantity などです。私はc ++を使用しています。助けてください。
これは私が読む必要があるファイルです。
Coca-Cola,0.75,20
Root Beer,0.75,20
Sprite,0.75,20
Spring Water,0.80,20
Apple Juice,0.95,20
これをそれぞれ変数にする必要があります。たとえば、drinkName、drinkCost、drinkQuantity などです。私はc ++を使用しています。助けてください。
これら 3 つの変数を 1 つのデータ型にまとめることをお勧めします。それを「DrinkT」と呼びましょう。
struct DrinkT{
std::string name;
float cost;
unsigned int quantity;
DrinkT(std::string const& nameIn, float const& costIn, unsigned int const& quantityIn):
name(nameIn),
cost(costIn),
quantity(quantityIn)
{}
};
これには多くの利点があります。
次のようなドリンクを作成できます。
DrinkT coke("Coca-Cola",0.75,20);
次のように変数にアクセスします。
std::cout << coke.name << std::endl; //outputs: Coca-Cola
std::cout << coke.cost << std::endl; //outputs: 0.75
std::cout << coke.quantity << std::endl; //outputs: 20
飲み物オブジェクトは、指定したもののみを保持します: 飲み物の名前、飲み物のコスト、飲み物の量。
オブジェクトには、構築時にこれら 3 つの値すべてを取るコンストラクターがあります。
つまり、すべての値を同時に指定した場合にのみ、drink オブジェクトを作成できます。
たくさんの飲み物オブジェクトを保存する場合 (そして、その数がわからない場合もあります)、それらを何らかのコンテナーに入れたいと思うかもしれません。
ベクトルは良い選択です。ベクトルは、保存したい飲み物の数だけ増加します。
ファイルをループして、3 つの値を個別に読み取り、ベクトルに格納してみましょう。ファイルの最後に到達するまで、ドリンクごとにこれを何度も繰り返します。
int main(){
std::ifstream infile("file.txt");
std::vector<DrinkT> drinks;
std::string name;
std::string cost;
std::string quantity;
std::getline(infile,name,',');
std::getline(infile,cost,',');
std::getline(infile,quantity,' ');
while (infile){
drinks.push_back(DrinkT(name,atof(cost.c_str()),atoi(quantity.c_str())));
std::getline(infile,name,',');
std::getline(infile,cost,',');
std::getline(infile,quantity,' ');
}
//output
for(DrinkT drink : drinks){
std::cout << drink.name << " " << drink.cost << " " << drink.quantity << std::endl;
}
return EXIT_SUCCESS;
}
g++ -std=c++0x -o main main.cpp でコンパイル
使用されている言語機能の一部に関する情報:
http://www.cplusplus.com/reference/string/getline/
http://www.cplusplus.com/reference/stl/vector/
いくつかの (すべてではない) 点で、私のアドバイスは @Xploit のアドバイスとほぼ同じです。データを保持するための構造体 (または必要に応じてクラス) を定義することから始めます。
struct soft_drink {
std::string name;
double price;
int quantity;
};
次に (大きな違い)operator>>
そのクラス/構造体に対して次のように定義します。
std::istream &operator>>(std::istream &is, soft_drink &s) {
// this will read *one* "record" from the file:
// first read the raw data:
std::string raw_data;
std::getline(raw_data, is);
if (!is)
return is; // if we failed to read raw data, just return.
// then split it into fields:
std::istringstream buffer(raw_data);
std::string name;
std::getline(buffer, name, ',');
double price = 0.0;
buffer >> price;
buffer.ignore(1, ',');
int quantity = 0;
buffer >> quantity;
// Check whether conversion succeeded. We'll assume a price or quantity
// of 0 is invalid:
if (price == 0.0 || quantity = 0)
is.setstate(std::ios::failbit);
// Since we got valid data, put it into the destination:
s.name = name;
s.price = price;
s.quantity = quantity;
return is;
}
これにより、入力ストリームから 1 つのレコードを読み取り、変換が成功したかどうかを知ることができます。1 つのレコードを読み取るコードができたら、残りはほとんど簡単になります。データのベクターを初期化するために正しい型の istream_iterator のペアを使用するだけです。
// read the data in one big gulp (sorry, couldn't resist).
//
std::vector<soft_drink> drink_data((std::istream_iterator<soft_drink>(infile)),
std::istream_iterator<soft_drink>());
あるアイテムを他のアイテムから分離する方法を調べることから始めます。
C++で文字列を分割するには? (スペースを通して)
その後、次の形式の新しい文字列が作成されます。drinkName,drinkCost,drinkQuantity
考えてみれば、アイテムの各情報を区切るのは記号(コンマ)なので、カンマで区切る方法も記載されているので、この投稿,
を確認する必要があります。
この情報を保存しやすくするために、3 つの変数を持つ新しいデータ型 (クラス) を作成できます。
class Drink
{
public:
std::string name;
std::string value; // or float
std::string quantity; // or int
};
std::vector<Drink>
最後に、すべての情報を内部に含めることができます。