全部,
我正在用 C++ 做一些编程练习,然后尝试将它们翻译成 C# 和其他语言来复习。
这个例子来自Ch。11.2 来自 Nell Dale 和 Chip Weems 的“使用 C++ 编程和解决问题”(第五版),第 521-522 页。这是一个接收这个文件的程序(学生姓名、GPA、四个成绩和课程成绩)——我们称之为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
乔艾伦·祖雷克 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
,但它一次只读取一个文件一行。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
,则会出现类型不匹配错误。或者,将其保留为不带单引号(因此将其保留为record.courseGrade
字段)会出现错误“The name 'A' does not exist in the current context.
我该如何最好地处理这个?-已解决
我对 ReadLine() 的困惑源于它的工作方式。在这种情况下,您有多个StudentRec
结构成员被填充,但它们是结构中的独立实体。我担心会做类似的事情:
StudentRec.stuName = inFile.ReadLine();
并StudentRec.stuName
填充了整行,其他结构字段中没有任何内容。
此外,我们还有letter
未分配并用作开关的问题;这是因为它从未从ReadLine
. 但是,这是一个学术解决方案,如果ReadLine
确实将事情分开的话。