全て、
私は C++ でいくつかのプログラミング演習を行っており、それらを C# や他の言語に翻訳してブラッシュアップしようとしています。
この例は、Ch. Nell Dale と Chip Weems の「Programming and Problem Solving with C++」(第 5 版) の 521 ~ 522 ページの 11.2。これは、このファイル (学生の名前、GPA、4 つの成績、コースの成績) を取り込むプログラムです。次のように呼びましょうrec.in
。
メアリー・アボット 3.4 80 90 60 99 B
ボブ・ベイカー 4.0 90 90 90 95 A
サリー・カーター 2.0 70 70 70 65 C
ビル・ダンスク 3.0 65 50 60 70 D
JoEllen Zureck 1.9 90 95 80 99 A
そして(多かれ少なかれ)それを別のファイルにコピーするだけです。
これを行うコードは次のとおりです。
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
const int MAX_STUDENTS = 150;
enum GradeType{A,B,C,D,F};
struct StudentRec
{
string stuName;
float gpa;
int examScore[4];
GradeType courseGrade;
};
StudentRec gradeBook[MAX_STUDENTS];
int main()
{
StudentRec record[MAX_STUDENTS];
ofstream outFile;
outFile.open("rec.out");
ifstream inFile;
inFile.open("rec.in");
for (int count = 0; count < MAX_STUDENTS; count++)
ReadValues(inFile, record[count]);
for (int count = 0; count <= MAX_STUDENTS; count++)
PrintValues(outFile, record[count]);
inFile.close();
outFile.close();
return 0;
}
void ReadValues(ifstream& inFile, StudentRec& record)
{
char letter;
char throwAway;
getline(inFile, record.stuName);
inFile >> record.gpa>>record.examScore[0]
>> record.examScore[1] >> record.examScore[2]
>> record.examScore[3] >> letter;
inFile.get(throwAway);
switch(letter)
{
case 'A' : record.courseGrade = A;
break;
case 'B' : record.courseGrade = B;
break;
case 'C' : record.courseGrade = C;
break;
case 'D' : record.courseGrade = D;
break;
case 'F' : record.courseGrade = F;
break;
}
}
void PrintValues(ofstream& outFile, StudentRec& record)
{
outFile << record.stuName << endl;
outFile << record.gpa << ' ' << record.examScore[0] << ' '
<< record.examScore[1] << ' '
<< record.examScore[2] << ' '
<< record.examScore[3] << ' ';
switch (record.courseGrade)
{
case A : outFile << 'A';
break;
case B : outFile << 'B';
break;
case C : outFile << 'C';
break;
case D : outFile << 'D';
break;
case F : outFile << 'F';
break;
}
outFile << endl;
}
私はC#への翻訳から始めています。以前に C# の作業を行ったことがありますが、コンソールの作業は行っていません。その結果、少し... 面倒です... 翻訳に取り組んでいます。私は、getline
C# で C++ の機能を一致させることに少し混乱しています。もちろん、ありますが、System.IO.StreamReader
それは一度に1行ずつファイルを読み取るだけです。getline
上記のように、ストリーム形式で実行します。これにより、単語/文字間のスペース/改行を使用して分割されます。C# のライブラリの選択で同じ結果を得るにはどうすればよいですか? 私はSystem.IO.StreamReader
解決策と正確に結婚していません。
これが私が持っているものの始まりです:
using System;
using System.IO;
namespace _112a
{
class Program
{
const int MAX_STUDENTS = 150;
enum GradeType{A,B,C,D,F};
struct StudentRec{
string stuName;
float gpa;
GradeType courseGrade;
};
StudentRec[] gradeBook = new StudentRec[MAX_STUDENTS];
static void Main(string[] args)
{
StudentRec[] record = new StudentRec[MAX_STUDENTS];
System.IO.StreamWriter outFile = new System.IO.StreamWriter("rec.out");
System.IO.StreamReader inFile = new System.IO.StreamReader("rec.in");
for (int count = 0; count < MAX_STUDENTS; count++)
{
ReadValues(inFile, record[count]);
}
for (int count = 0; count <= MAX_STUDENTS; count++)
{
PrintValues(outFile, record[count]);
}
inFile.Close();
outFile.Close();
}
static void ReadValues(StreamReader inFile, StudentRec record)
{
char letter;
char throwAway;
/*can't use getline, what do?*/
inFile.ReadLine();
switch (letter)
{
case 'A':
record.courseGrade = (GradeType)Enum.Parse(typeof(GradeType), "A");
break;
case 'B':
record.courseGrade = (GradeType)Enum.Parse(typeof(GradeType), "B");
break;
case 'C':
record.courseGrade = (GradeType)Enum.Parse(typeof(GradeType), "C");
break;
case 'D':
record.courseGrade = (GradeType)Enum.Parse(typeof(GradeType), "D");
break;
case 'F':
record.courseGrade = (GradeType)Enum.Parse(typeof(GradeType), "F");
break;
}
}
static void PrintValues(StreamWriter outFile, StudentRec record)
{
outFile.Write("{0}\n{1} {2} {3} ", record.stuName, record.examScore[0], record.examScore[1], record.examScore[2], record.examScore[3]);
switch(record.courseGrade)
{
case GradeType.A:
outFile.Write("A\n");
break;
case GradeType.B:
outFile.Write("B\n");
break;
case GradeType.C:
outFile.Write("C\n");
break;
case GradeType.D:
outFile.Write("D\n");
break;
case GradeType.F:
outFile.Write("F\n");
}
}
}
}
メソッドに表示されるスイッチ構造に関して追加の質問がありますPrintValues
。それぞれのケースで、C++ ファイルで指定されているように、record.courseGrade
フィールドを取得して、後ろに指定された引数と比較するだけcase
です。型に強い言語である C# では、このようなことは起こりません... char
'A' をと比較するrecord.courseGrade
と、型の不一致エラーが発生します。または、一重引用符を付けずにそのままにしておく (したがって、フィールドとして残す) と、 How do I best deal with this?- RESOLVEDrecord.courseGrade
のエラーが発生します。The name 'A' does not exist in the current context.
ReadLine() を使用した私の混乱は、それがどのように機能するかに起因します。この場合、構造体の複数のメンバーStudentRec
が満たされていますが、それらは構造体の個別のエンティティです。私の恐れは次のようなことをするでしょう:
StudentRec.stuName = inFile.ReadLine();
StudentRec.stuName
他の構造体フィールドには何も入力せずに、行全体を入力します。
さらに、letter
割り当てが解除されてスイッチとして使用されるという問題があります。これは、 から値を受け取っていないためReadLine
です。ReadLine
ただし、実際に物事を分割する場合、それは学術的な解決策です。