所以我正在练习使用C ++中的文件。我创建了一个简单的程序,可以加载学生的姓名,索引号,出生日期和STUDENT.txt
的成绩,计算学生的平均成绩,并将其全部写在下面的表格中到另一个档案。
这一切都像魅力一样,除了一件事:它吃掉了每一行的第一个字母。例: 我有一个看起来像这样的STUDENT.txt文件:
Alice Cooper
225883
21/6/1986
6,6,8,9,10
Zakk Wylde
27568
14/5/1978
6,6,6,6,6
所以第一个学生Cooper将被正确处理,但文件中的其他人都不会。他们将被写成'akk Wylde'...... 所以除了名字之外的一切都可以。 我希望有人可以告诉我到底发生了什么,我猜它正在吃掉'\ n'和另一个角色,但我无法通过调试找到它。
// Student_datoteka.cpp:定义控制台应用程序的入口点。 //
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
std::string toString(int day, int month, int year) {
std::string d, m, g, ret;
d = std::to_string(day);
m = std::to_string(month);
g = std::to_string(year);
ret += d;
ret += "/";
ret += m;
ret += "/";
ret += g;
return ret;
}
int main()
{
std::fstream load("STUDENTI.txt", std::ios::in);
std::ofstream write("IZVJESTAJ.txt");
write << std::setw(30) << std::left << "Student"
<< std::setw(10) << "Indeks"
<< std::setw(20) << "Datum rodjenja"
<< std::setw(10) << "Prosjek" << std::endl;
write << std::setw(30) << std::left << "-------"
<< std::setw(10) << "------"
<< std::setw(20) << "--------------"
<< std::setw(10) << "-------" << std::endl;
if (!write)
std::cout << "ERROR!";
std::string name;
int indeks(0), day(0), month(0), year(0);
char sign(0), sign2(0);
int grades[30];
double average(0);
while (std::getline(load, name)) {
if (load.eof()) break;
load >> indeks;
load >> day >> sign >> mjesec >> sign2 >> year;
int i(0);
while (load >> grades[i]) {
load >> sign;
average += grades[i];
i++;
}
average /= double(i);
std::string datum = toString(day, month, year);
write << std::setw(30) << std::left << name
<< std::setw(10) << indeks
<< std::setw(20) << datum
<< std::setw(10) << std::setprecision(2)
<< average<< std::endl;
average = 0;
if (load.eof()) break;
load.clear();
}
return 0;
}
答案 0 :(得分:0)
我对您的代码进行了一些小改进,所以如果您不喜欢,请仅使用工作部分。请注意,我的代码可以进一步改进和推广,但我将其留给您。
希望你想要我的解决方案:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
typedef struct Student
{
std::string name;
int index_no;
int day_of_birth;
int month_of_birth;
int year_of_birth;
std::vector<int> grades;
double avg_grade;
} Student;
std::string date_to_string(int day, int month, int year)
{
std::string d, m, g, ret;
d = std::to_string(day);
m = std::to_string(month);
g = std::to_string(year);
ret += d;
ret += "/";
ret += m;
ret += "/";
ret += g;
return ret;
}
void get_date_from_str(int& day, int& month, int& year, std::string const& str)
{
std::stringstream ss(str);
ss >> day;
ss.ignore(1);
ss >> month;
ss.ignore(1);
ss >> year;
}
void get_numbers_from_str(std::vector<int>& vec, std::string const& str)
{
std::stringstream ss(str);
int i;
while (ss >> i)
{
vec.push_back(i);
ss.ignore(1);
}
}
double calculate_avg(std::vector<int> const& vec)
{
int sum = 0;
for (auto item : vec)
{
sum += item;
}
return (double) sum / vec.size();
}
int main()
{
std::ifstream students_file("students.txt");
std::ofstream report_file("report.txt");
if (students_file.is_open() && report_file.is_open())
{
report_file << std::setw(30) << std::left << "Student"
<< std::setw(10) << "Indeks"
<< std::setw(20) << "Datum rodjenja"
<< std::setw(10) << "Prosjek" << std::endl;
report_file << std::setw(30) << std::left << "-------"
<< std::setw(10) << "------"
<< std::setw(20) << "--------------"
<< std::setw(10) << "-------" << std::endl;
std::vector<Student> students;
std::string name;
while (std::getline(students_file, name))
{
std::string index_no;
std::string date_of_birth;
std::string grades;
Student student;
student.name = name;
std::getline(students_file, index_no);
std::stringstream(index_no) >> student.index_no;
std::getline(students_file, date_of_birth);
std::getline(students_file, grades);
get_date_from_str(student.day_of_birth, student.month_of_birth, student.year_of_birth, date_of_birth);
get_numbers_from_str(student.grades, grades);
student.avg_grade = calculate_avg(student.grades);
students.push_back(student);
}
for (auto student : students)
{
report_file << std::setw(30) << std::left << student.name
<< std::setw(10) << student.index_no
<< std::setw(20) << date_to_string(student.day_of_birth, student.month_of_birth, student.year_of_birth)
<< std::setw(10) << std::setprecision(2)
<< student.avg_grade << std::endl;
}
}
else
{
std::cout << "Unable to open one of the files!" << std::endl;
}
return 0;
}
首先,我认为你的代码已经复杂化,阅读和理解它们,而你有一些C ++特性可以用标志和解析日期和等级简化这部分。
我还创建了struct Student
,并将部分代码拆分为函数。
并且,关于您的解决方案。正如评论中已经提到的那样,错误在于以下几点:
while (load >> grades[i])
{
load >> sign;
average += grades[i];
i++;
}
你正在吃饭&#39;超过你需要的一个角色。而这个角色是第二个学生名字的第一个角色。因此,如果您将代码更改为以下内容,您就会看到我在谈论的内容:
while (load >> grades[i])
{
if (i != 4) // just a temporary solution, since the first student has 5 grades
load >> sign;
average += grades[i];
i++;
}