0

さて、私はプログラミングの初心者なので、優しくしてください。これまでのところ、C ++のみを学習しており、コンパイラとしてVisualStudio2010を実行しています。このプログラムでは、テキスト入力ファイルから読み取り、3つの配列のセットに情報を書き込もうとしています。1つの配列は名前のリストを処理し、他の2つはそれぞれ労働時間と時給です。後者の2つを使用して一連の収益を計算し、それらの計算を別のテキストファイルに出力します。ただし、私の問題は、最初の配列の入力を取得することです。私が使用している入力ファイルには、次のように配置されたテキストがあります。

J. Doe * 35 12.50

J.ドーン*2010.00........。

ifstream getlineを使用して、アスタリスクが区切り文字として機能する名前を取得し、次の2つの数値を他の2つの配列に書き込んでいるため、名前の末尾にはアスタリスクが付いています。後者の2つの値は空白で区切られているため、問題が発生することはないと思います。処理が必要な他のエラーがあると確信していますが、残りのデバッグを開始する前に、最初のエラーを処理する必要があります。inFile.getlineを呼び出す行でエラーが発生しました。これは次のようになります。

エラーC2664:'std :: basic_istream <_Elem、_Traits>&std :: basic_istream <_Elem、_Traits> :: getline(_Elem *、std :: streamsize、_Elem)':パラメータ1を'std::string'から'に変換できません'char*'。

私が他の場所で読んだことから、(私が思うに)問題は文字列をchar配列に書き込もうとすることに起因しますが、それらは異なるデータ型であるため機能しません。名前を数値から分離するための区切り文字が必要なため、名前を取得するための他の実行可能な方法が存在するかどうかはわかりません。この問題を解決する方法についてのアドバイスをいただければ幸いです。

これが私が書いた情報源です:

#include <iostream>  
#include <fstream>   
#include <iomanip>  
#include <string>  
using namespace std;  

const int EMP_NUM = 5;  
const int BASE_HOURS = 40;  
const char N_SIZE = 8;  

int main()
{
 int i;
 double rEarnings, oEarnings, tEarnings,
 trEarnings, toEarnings, ttEarnings;
 ifstream inFile;
 ofstream outFile;
 inFile.open("records.txt");
 outFile.open("report.txt");

 outFile << setprecision(2) << showpoint << fixed;

 outFile << setw(50) << "Payroll Report" << "\n\n";
 outFile << "EMPLOYEE NAME" << setw(25) << "REGULAR EARNINGS" << setw(25) << "OVERTIME EARNINGS" << setw(25) << "TOTAL EARNINGS" << endl;

 string nameAr[EMP_NUM];
 int hoursAr[EMP_NUM];
 double hrateAr[EMP_NUM];

 for (int i = 0; i < EMP_NUM; i++) // Get input from our input file.
 {
  inFile.getline(nameAr[i], EMP_NUM, "*");
  inFile >> hoursAr[i] >> hrateAr[i];
 }

 for (int i = 0; i < EMP_NUM; i++) // Make the calculations to be sent to our report.
 {
  char nameAr[N_SIZE];
  int hoursAr[N_SIZE];
  double hrateAr[N_SIZE];

  if (hoursAr[i] > 40) // For employees with overtime hours.
  {
  // double rEarnings, double oEarnings, double tEarnings,
  // double trEarnings, double toEarnings, double ttEarnings;
  // rEarnings = 0, oEarnings = 0, tEarnings = 0,
  // trEarnings = 0, toEarnings = 0, ttEarnings = 0;

   rEarnings = BASE_HOURS * hrateAr[i];
   oEarnings = (hoursAr[i] - BASE_HOURS) * hrateAr[i] * 1.5;
   tEarnings = rEarnings + oEarnings;
   trEarnings += rEarnings;
   toEarnings += oEarnings;
   ttEarnings += tEarnings;
   outFile << left << nameAr[i];
   // << setw(25) << right << rEarnings << setw(25) << right << oEarnings << setw(25) << right << tEarnings << endl;

  } 
  else // For employees without overtime hours.
  {
   double rEarnings, double oEarnings, double tEarnings,
   double trEarnings, double toEarnings, double ttEarnings;
   rEarnings = 0, oEarnings = 0, tEarnings = 0,
   trEarnings = 0, toEarnings = 0, ttEarnings = 0;

   rEarnings = hoursAr[i] * hrateAr[i];
   oEarnings = 0;
   tEarnings = rEarnings + oEarnings;
   trEarnings += rEarnings;
   toEarnings += oEarnings;
   ttEarnings += tEarnings;
   outFile << left << nameAr[i] << setw(25) << right << rEarnings << setw(25) << right << oEarnings << setw(25) << right << tEarnings << endl;
  }
 }

 outFile << endl << endl;

 outFile << setw(33) << trEarnings << " *" << setw(23) << toEarnings << " *" << setw(23) << ttEarnings << " *\n\n";

 outFile << left << "TOTAL EMPLOYEES" << " " << (i - 1);

 inFile.close(); outFile.close();

 return 0;
}

プログラム全体を含めて、コーディングをどこに進めるかについてのアイデアを提供します。助けてくれてありがとう!

4

2 に答える 2

1

こんにちはC++の新しいプログラマー!C /C++でのコーディングの素晴らしさへようこそ。

あなたがC++を始めたばかりだと知っています。しかし、問題を解決するには、少しCに触れる必要があります。C++はたまたまCのスーパーセットです。つまり、Cで実行できることはすべてC++プログラムで機能します。

十分な言葉、コード時間。入力ファイルから入力を取得するために使用するコードを次のように置き換えます。

char tmp[256];
memset(tmp, '\0', sizeof tmp);
inFile.getline(tmp, EMP_NUM, '*');
nameAr[i] = tmp;
inFile >> hoursAr[i] >> hrateAr[i];

それを見ていきましょう。

char tmp[256];値を読み取るための一時配列を作成します。この配列のサイズは、受け取る名前の平均の長さによって異なる場合があります。

Cの弦は、メンテナンスの行き届いたシックなものです。最後にNULL文字を指定する必要があります'\0'。そうしないと、それほど明白ではないセグメンテーション違反でプログラムがクラッシュする可能性があります。ただし、Memsetは、コンピューターの鉱山で働く小さな男です。彼は私たちがこれを修正するのを手伝ってくれるでしょう。この形式で呼び出されるとmemset(tmp, '\0', sizeof tmp)、memsetはのアドレスから始まりtmp、配列のすべてのビット(サイズIDはsizeof tmp-として指定)をウォークスルーし、これらのビットを指定された文字(この場合はNULL)に設定します。このようにして、C文字列を読み取るたびにNULL文字を追加することを覚えておく必要はありません。tmpのサイズが十分に大きい場合。便利!

inFile.getline(tmp, EMP_NUM, '*');期待どおりにファイルから入力[文字列]を読み取り、tmpに保存します。

nameAr[i] = tmp;読み取った入力をnames配列に入れます。

そして最後に、inFile >> hoursAr[i] >> hrateAr[i];以前と同じように時間と時給を読み取ります。

お役に立てれば。

乾杯!幸せな学習。

于 2010-11-06T08:19:00.160 に答える
1

getline処理する2つの別々の区切り文字(スペースとアスタリスク)があるため、この方法では使用しません。代わりにこれを行います。

getlineFULL行をstring呼び出されたに取得するために使用しますline

を使用してアスタリスクを検索しますline.find('*');

見つかった位置までをstring使用して、名前を新しいものとして抽出しますline.substr

substrアスタリスクを超えて、stringstreamと呼ばれるに別のものを取りますremainder

intを使用して、をdouble直接読み取りoperator>>ます。remainder >> hours >> rate;

于 2010-11-05T18:54:09.017 に答える