Реализация пары ключ-значение C

у меня есть .txt файл, в котором хранятся имена учеников и две их лучшие оценки. Если студент по какой-то причине, то есть бросает учебу, не проходит курс, то оценки не записываются.

Мой файл выглядит так

Samuel= 90.5, 95.9
Bill= 25.2, 45.3
Tim
Anthony= 99.9, 12.5
Mark
Rob

В принципе, Tim, Mark а также Rob провалил курс и следовательно их оценки не сохраняются. Кроме того, чтобы провести различие между неудавшейся отметкой и проходной отметкой, я использовал = условное обозначение. По сути, я хочу сохранить все имена в памяти вместе с соответствующими значениями.

Это моя реализация, однако она несовершенна в том смысле, что я объявил double *marks[2] массив для хранения всех шести меток, когда ясно, что он будет хранить только 3. У меня проблемы с сохранением значений в double массив.

Это мой код …

istream& operator>> (istream& is, Students& student)
{
student.names = new char*[6];
for (int i=0; i<10; i++)
{
student.names[i] = new char[256];
student.marks[i] = new double[2];
is.getline(student.names[i], sizeof(student.names));

for (int j=0; j < 256; j++)
{
if((student.names[i][j] == '='))
{
int newPos = j + 1;
for (int k = newPos; k < 256; k++)
{
student.names[i][k - newPos] = student.names[k];
}
}
}
}
}

Как я могу хранить ценности учеников с действительными оценками? Пожалуйста, не используйте vectors или же stringstreams, просто чистый C / C ++ char arrays

0

Решение

У вас есть несколько вариантов, вы можете использовать struct вот так

struct Record {
std::string name;
double marks[2];
};

А потом воткнуть это во что-то вроде std::vector<Record> или массив из них, как

Records *r = new Records[1000];

Вы также можете сохранить три разных массива (автоматически или динамически или даже std::vector), один, чтобы держать имя, два, чтобы держать знаки.

В каждом случае вы просто указали бы на сбой с помощью некоторой вещи, например, отметки равны нулю.

Также вы можете использовать

std::string name;
double first, second;
std::cin >> name;
if (name[name.size() - 1] == '=')
std::cin >> first >> second;

И это будет анализировать ввод, как вы хотите, для одной строки. Как только вы это сделаете, вы можете обернуть все это в цикл, вставив значения, которые вы получите в какую-то структуру данных, которую я уже описал.

Надеюсь, что это даст вам несколько идей о том, куда идти!

0

Другие решения

Вот стратегия:

Прежде всего вам нужно реализовать struct для хранения пары ключ-значение я предлагаю следующее:

struct Student {
char name[30];
double marks[2];
};

Обратите внимание, что вы можете указать размер массива char внутри struct если вы знаете, что длина никогда не будет выше. (что дано здесь)

Теперь вам нужно знать, сколько строк в вашем ifstreamВы могли бы сделать петлю is.getline() звонки, чтобы добраться туда. (не забудьте позвонить is.clear() а также is.seekg(0) когда закончите, чтобы быть в начале для реального цикла)

Когда вы знаете, сколько строк в вашем потоке ifstream, вы можете динамически использовать массив ваших struct с фактической длиной вашего файла:

Student * students = new Student[lineCount]; // line count of is

Как видите, нет необходимости иметь std::vector держать значения. Считайте, что getline() Цикл может быть излишним просто для того, чтобы получить количество строк, или же вы можете указать длину для студентов во время компиляции, создав массив с длиной, которая никогда не будет превышена.
(например. Student students[128];)

Теперь вам нужно разобрать строки, я бы посоветовал сделать цикл, подобный следующему (строка за строкой):

// int parseLine ( char* line, char* name, double* marks ) { ...
bool hasMarks=false;
int iLine=0; // Line pos iterator
int iName=0; // Name pos iterator
char mk1Str[4]; // String buffer, Mark 1
char mk2Str[4]; // String buffer, Mark 2

while(line[iLine]!='\0')
{
if(line[iLine]=='=')
{
hasMarks=true;
name[iLine]='\0';

for(int iMark=0;iMark<4;iMark++)
{
mk1Str[iMark]=line[iLine+iMark+2];
mk2Str[iMark]=line[iLine+iMark+8];
// ^^ You can harcode the offsets (2,8) since they don't change
}
break;
}
name[iName++]=line[iLine];
iLine++;
}

Теперь вам нужно разобрать оценки double значения, для этого вы можете использовать atof() функция, которая работает с char*, Бул hasMarks поможет вам узнать, если ученик определил оценки, если нет, вы можете определить фиктивные значения, такие как -1, для полей оценки вашего struct,

Я думаю, что это работает довольно хорошо для вашего случая …

0

По вопросам рекламы [email protected]