Все,Транслейтинг C++ чтение файла/записи для чтения C# Файл/записи
Я делаю некоторые упражнения программирования на C++, а затем пытается перевести их на C# и других языках, чтобы освежить.
Этот пример исходит из главы. 11.2 из Нелл Дейл и Чипа Вейса «Программирование и решение проблем с помощью С ++» (пятое издание), с. 521-522. Это программа, которая принимает в этом файле (имя студента, ГПД, четыре класса, а класс курса) - давайте назовем его rec.in
:
Mary Abbott 3,4 80 90 60 99 B
Боб Бейкер 4.0 90 90 90 95
Салли Картер 2.0 70 70 70 65 С
Билл Dansk 3.0 65 50 60 70 D
JoEllen Zureck 1,9 90 95 80 99
А (более или менее) просто копирует его в другой файл.
Вот код, чтобы сделать это:
#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
действительно делит вещи.
Эти выходные данные на консоли. Я ищу для вывода в файл. – nerdenator
@AaronMcRuer да, я вижу это сейчас. Обновлено с соответствующей информацией. – evanmcdonnal
Должен ли я каким-то образом пройти через поток? Я думаю, что я немного не понимаю, как он сравнивается с реализацией на C++. Реализация C++ - это поток, конечно, поэтому вещи разбиваются на куски, но реализация C# представляет собой функциональную реализацию. – nerdenator