我在读取一个文件,然后将其分配给结构数组并打印出来时遇到了问题



我目前必须获取一个input.txt文件,该文件类似于

3

Sarah 90 40 30

约翰23 55 33

帮助34 99 74

作为输入文件,

并将其读取到一个结构数组中,然后创建一个output.txt.

我的作业好像有问题。我尝试了fscanf、fgetc、fgets、strtok、delim和我在互联网上能找到的所有东西,但由于我对指针的了解不全面,我似乎被卡住了。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
typedef struct studentT{
char *name;
int literature;
int math;
int science;
}studentT;
int main(void)
{
printf("Start of mainn");
FILE *fptr;
int i;
fptr = fopen("input.txt", "r");
//reading first line to dynamically allocate studentT
printf("dynamically allocating studentTn");
char tempsize[4];
//fgets(tempsize,1,fptr);
//i=atoi(&tempsize[0]);
fscanf(fptr,"%d",&i);
struct studentT* record = malloc(i*sizeof(*record));
printf("i has interger value %dn", i);
//line counter ignoring line 0; reading 1 and 2.
char line[24];
char buffer[24];
char delim[] = " ";
char *array[4];
int *darray[4];
printf("entering while loopn");
fgets(buffer,24,fptr);
int idx =0;
while(fgets(line, sizeof(line),fptr)!=NULL &&idx<i)
{
puts(line);
char *buf = strtok(line, delim);
int iter =0;
while(buf!=NULL)
{
if(iter = 0){
array[iter]=buf;
buf = strtok(NULL,delim);
}
for(iter=1;iter<4;iter++){
*darray[iter] =atoi(buf);//
printf("%d,",*darray[iter]);
buf=strtok(NULL, delim);
}
}

record[idx].name=array[0];
record[idx].literature=*darray[1];
record[idx].math=*darray[2];
record[idx].science=*darray[3];
//    printf("array value: %s %d %d %dn",array[0], array[1], array[2], array[3]);
//    printf("value after casting: %s %zu %zu %zun", array[0], (uintptr_t)array[1], (uintptr_t)array[2], (uintptr_t)array[3]);
//sscanf(buf,"%s %d %d %d",record[idx].name, &record[idx].literature, &record[idx].math, &record[idx].science);
printf("%sn", line);
//fscanf(fptr,"%s %d %d %d",record[idx].name, &record[idx].literature, &record[idx].math, &record[idx].science);
line[strlen(line)-1]='';    
printf("in idx loop %d %s %d %d %dnn", idx, record[idx].name, record[idx].literature, record[idx].math, record[idx].science);
idx++;
}
//output of file
printf("output commencingnnn");
int tempave;
FILE *fout;
char *str1 = "Name Literature Math Science Ave.n";
char *str2 = "Ave. ";
char *str3 = "Saraht 96t 90t 80t 88.67";
char *str4 = "Minsut 55t 70t 76t 67.00";
char *str5 = "Narat 88t 70t 96t 84.67";
char *str6 = "79.67 76.67 84.00 80.11";
fout = fopen("output.txt", "w");
fprintf(fout,"%sn", str1);

for(int idx=0;idx<i;idx++){
tempave = (record[idx].math+record[idx].literature+record[idx].science)/3;
fwrite(&record[idx],sizeof(struct studentT),1,fout);
fprintf(fout, "%dn",tempave);
}
//fprintf(fout, "%sn %sn %sn %s %sn",str3,str4,str5,str2,str6); 

fprintf(fout,"%s",str2);
float mathave,litave,sciave;
for(int idx=0;idx<3;idx++){
mathave+=record[idx].math;
litave+=record[idx].literature;
sciave+=record[idx].science;
}
mathave=mathave/3;
sciave=sciave/3;
litave=litave/3;
fprintf(fout,"%f %f %f",litave, mathave, sciave);
fclose(fptr);
fclose(fout);
}

编辑:同事提到我应该malloc数组,这样代码现在看起来更难看:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
typedef struct studentT{
char *name;
int literature;
int math;
int science;
}studentT;
int main(void)
{
printf("Start of mainn");
FILE *fptr;
int i;
fptr = fopen("input.txt", "r");
//reading first line to dynamically allocate studentT
printf("dynamically allocating studentTn");
char tempsize[4];
//fgets(tempsize,1,fptr);
//i=atoi(&tempsize[0]);
fscanf(fptr,"%d",&i);
struct studentT* record = malloc(i*sizeof(*record));
printf("i has interger value %dn", i);
//line counter ignoring line 0; reading 1 and 2.
char line[24];
char buffer[24];
char delim[] = " ";
char *array[4];
int darray[4];
printf("entering while loopn");
fgets(buffer,24,fptr);
int idx =0;
while(fgets(line, sizeof(line),fptr)!=NULL &&idx<i)
{
puts(line);
char *buf = strtok(line, delim);
int iter =0;
while(buf!=NULL)
{
if(iter = 0){
array[iter] = malloc(sizeof(char)*strlen(buf));
strcpy(array[iter],buf);
buf = strtok(NULL,delim);
}
for(iter=1;iter<4;iter++){
darray[iter] = (int*)malloc(sizeof(char)*strlen(buf));
memcpy(&darray[iter],buf,(sizeof(char)*strlen(buf)));//
buf=strtok(NULL, delim);
}
}

record[idx].name=malloc(sizeof(char)*strlen(array[0]));
strcpy(record[idx].name,array[0]);
record[idx].literature=darray[1];
record[idx].math=darray[2];
record[idx].science=darray[3];
//    printf("array value: %s %d %d %dn",array[0], array[1], array[2], array[3]);
//    printf("value after casting: %s %zu %zu %zun", array[0], (uintptr_t)array[1], (uintptr_t)array[2], (uintptr_t)array[3]);
//sscanf(buf,"%s %d %d %d",record[idx].name, &record[idx].literature, &record[idx].math, &record[idx].science);
printf("%sn", line);
//fscanf(fptr,"%s %d %d %d",record[idx].name, &record[idx].literature, &record[idx].math, &record[idx].science);
line[strlen(line)-1]='';    
printf("in idx loop %d %s %d %d %dnn", idx, record[idx].name, record[idx].literature, record[idx].math, record[idx].science);
idx++;
}
//output of file
printf("output commencingnnn");
int tempave;
FILE *fout;
char *str1 = "Name Literature Math Science Ave.n";
char *str2 = "Ave. ";
char *str3 = "Saraht 96t 90t 80t 88.67";
char *str4 = "Minsut 55t 70t 76t 67.00";
char *str5 = "Narat 88t 70t 96t 84.67";
char *str6 = "79.67 76.67 84.00 80.11";
fout = fopen("output.txt", "w");
fprintf(fout,"%sn", str1);

for(int idx=0;idx<i;idx++){
tempave = (record[idx].math+record[idx].literature+record[idx].science)/3;
fwrite(&record[idx],sizeof(struct studentT),1,fout);
fprintf(fout, "%dn",tempave);
}
//fprintf(fout, "%sn %sn %sn %s %sn",str3,str4,str5,str2,str6); 

fprintf(fout,"%s",str2);
float mathave,litave,sciave;
for(int idx=0;idx<3;idx++){
mathave+=record[idx].math;
litave+=record[idx].literature;
sciave+=record[idx].science;
}
mathave=mathave/3;
sciave=sciave/3;
litave=litave/3;
fprintf(fout,"%f %f %f",litave, mathave, sciave);
fclose(fptr);
fclose(fout);
}

我已经为您编写了一个新版本的注释。希望您能够理解正在发生的事情并修复您的代码,或者也可以使用它。您可能需要更改inputfile和outputfile的名称才能使用输入文件。

#include <stdio.h>
#include <stdlib.h>
struct student {
char *name;
int literature;
int math;
int science;
};
typedef struct student Student;
int main(void) {
FILE* inputFile;
FILE* outputFile;
int first_read; //check to see if the number of students value was read
int readNumStudents; //count of how many students are there
int i; //tracking students struct array
Student* students; //array of student structs
readNumStudents = 0;
first_read = 0;
i = 0;
inputFile = fopen("input.txt", "r"); //might have to change to whatever your file name is
outputFile = fopen("output.txt", "w"); //might have to change to whatever you want the output file name to be
//checking for null  file pointers 
if(inputFile == NULL){
printf("Failed to open input file.n");
exit(1);
}
if(outputFile == NULL){
printf("Failed to open output file.n");
exit(1);
}
//read file until end of file is reached
while(!feof(inputFile)){
if (first_read == 0){// check to see if first line was read. if not read, then write the value to readNumStudents variable
fscanf(inputFile, "%d", &readNumStudents);
first_read = 1; //set the value to 1. this means that the number of students was read.
students = (Student*) malloc(sizeof(Student) * readNumStudents);//allocate Student structs for the number of given students fro input file. (ie. 3 structs)
if(students == NULL){//check for null
printf("Failed to allocate memory for students.n");
break;
}
//If not null, then for every struct allocate memory for the name string because its char* not char name[50]
for(int j = 0; j < readNumStudents; j++){
students[j].name = (char*) malloc(sizeof(char) * 50);
if(students[j].name == NULL){//check for null
printf("Failed to allocate memory for name.n");
exit(1);
}
}
} else {//this means that the first line was read. now read the names and scors
//since you know the format of the input file (string int int int) you can use fscanf with "%s %d %d %d" and the adress of the struct values
fscanf(inputFile, "%s %d %d %d",  students[i].name, &(students[i].literature), &(students[i].math), &(students[i].science));
i++;//used to point to next student structure
}
}
//Go thorugh every struct and write each value to outputfile
for(int j = 0; j < i; j++){
fprintf(outputFile, "%s %d %d %dn", students[j].name, (students[j].literature), (students[j].math), (students[j].science));
}
//free all the allocated memory and files
fclose(inputFile);
fclose(outputFile);
//you need to free the char array on top of the studnets struct array. so loop through every student to free it
for(int j = 0; j < i; j++){
free(students[j].name);
}
free(students);
return 0;
}

最新更新