我的任务是创建一个程序来完成结构的一些东西。我的结构是关于学生的记录(考试成绩)。
我的交换机中第一种情况下的函数创建了结构并将其写入文件。第二个 - 从文件中读取它。这是我的代码:
#include <stdio.h>
#include <stdlib.h>
struct session {
char name[50];
int group;
int exam1;
int exam2;
int exam3;
int exam4;
char test1[50];
char test2[50];
};
void create(int);
void show(int);
int main() {
int i, n;
int loop = 2, num;
while(loop > 1) {
printf("\nChoose menu item(1-4):");
scanf("%d", &num);
switch (num) {
case 1:
printf("The number of students:\n");
scanf("%d", &n);
create(n);
break;
case 2:
show(n);
break;
case 3:
break;
case 4:
break;
default:
loop = 0;
break;
}
};
return 0;
}
void create(int n) {
FILE *fp;
session *year2017 = new session[n];
fp = fopen("lab8.txt", "w");
if(fp == NULL) {
printf("File can't be opened\n");exit(1);
}
for (int i = 0; i < n; i++) {
printf("Student #%d\n", i + 1);
printf("Student's family name: ");
while (getchar() != '\n');
fgets(year2017 -> name, 50, stdin);
printf("Group number: ");
scanf("%d", &year2017->group);
printf("1st exam grade: ");
scanf("%d", &year2017->exam1);
printf("2d exam grade: ");
scanf("%d", &year2017->exam2);
printf("3d exam grade: ");
scanf("%d", &year2017->exam3);
printf("4th exam grade: ");
scanf("%d", &year2017->exam4);
printf("First test (passed or not): ");
while (getchar() != '\n');
fgets(year2017 -> test1, 50, stdin);
printf("Second test (passed or not): ");
fgets(year2017 -> test2, 50, stdin);
fwrite(year2017, sizeof(session), 1, fp);
}
fclose(fp);
}
void show(int n){
FILE *fp;
session *year2017 = new session[n];
fp = fopen("lab8.txt", "r");
while(fread(year2017,sizeof(session), 1, fp) != NULL) {
printf("%s %d %d %d %d %d %s %s", year2017->name, year2017 ->
group, year2017 -> exam1, year2017 -> exam2, year2017 -> exam3,
year2017 -> exam4, year2017 -> test1, year2017 -> test2);
}
fclose(fp);
}
当我编译代码时,输入如下:
因此它不会在第二个循环中找到学生的名字,也会将成绩和第二个考试转移到新行。
我使用Clion和Mac OS。
答案 0 :(得分:0)
在c ++中,另一种选择是在文件中写入或读取一些数据
示例(尝试这样):
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void writeFile()
{
ofstream myfile;
myfile.open("example.txt");
if (myfile.is_open())
{
myfile << "Writing this to a file.\n";
myfile.close();
}
else
std::cout << "fail" << std::endl;
}
void readFromFile()
{
std::ifstream file("example.txt");
std::string str;
while (std::getline(file, str))
{
std::cout << str << std::endl;
}
}
int main()
{
writeFile();
readFromFile();
return 0;
}
答案 1 :(得分:0)
std::fgets
保留字符串输入后的换行符(假设缓冲区空间足以达到它)。因此,您的test
成员和name
成员会在其尾部包含 这些新行。
这可以准确地解释您的输出。最直接的解决方法是简单地删除这些字符串中的换行符(如果存在),最合适的时间是阅读它们之后。语法类似于:
char *p = strrchr(str, '\n');
if (p)
*p = 0;
这将找到换行符(如果允许空格,则必须是读取的最后一个字符)并用终止的nulchar覆盖它。
第二个问题是丢失name
,因为循环(while (getchar() != '\n');
)的 top 处的修剪代码不应该在循环内。这是在菜单选择后修剪换行符。它属于那里(菜单选择后);不在这个循环中。
所有这些都表示,在这段代码中有很多值得做的事情,它们对IO操作的成功有很多的假设,并且像筛子一样泄漏内存泄漏。拥抱标准C ++库并利用其众多功能将有助于大多数这些,我鼓励您这样做。
无论如何,上面应该解决你关于奇数输出的问题。