0

I am trying to write text to a file using loops, but when I make it like (ogrenci+i) using i and not like (ogrenci+0) I'm getting some weird numbers and text in txt file.

When writing like this (ogrenci+0) it works correctly. What am I doing wrong?

I attent pointer to struct in a different function.

this is the question QUESTIONS

Assume that you are given the structure below

typedef struct StudentMark {
char name[20];
char surname[20];
int midterm;
int final;
}STUDENT_MARK;

1-) Write down a program which contains

a-) A function to get the user entered name, surname, and exam marks into dynamically allocated STUDENT_MARK structure (your function MUST check input validity i.e entered marks must between [0..100]).

b-) A function to write down the entered VALID structures into a file named as marks_YOUR_STUDENT_ID.txt.

2-) Write a program which contains

a-) A function to read a file named as marks_YOUR_STUDENT_ID.txt which contains STUDENT_MARK structures’ data.

b-) A function to calculate the average of each student’s exam marks and writes the result onto screen as

“The student NAME SURNAME’s midterm mark is MIDTERM, final mark is FINAL and his/her average is AVERAGE”

void girme (int studentnum){
int i;
studentnum = 2;
STUDENT_MARK *ogrenci;

ogrenci = (STUDENT_MARK*) malloc(studentnum * sizeof(STUDENT_MARK));
if(ogrenci == NULL) { exit(1); }

for(i=0;i<studentnum;i++)
{

printf("Enter the student's name, surname, midterm and final respectively: \n");
scanf("%s %s %d %d",(ogrenci+i)->name, (ogrenci+i)->surname, &(ogrenci+i)->midterm, &(ogrenci+i)->final);

if((ogrenci+i)->midterm > 100 || (ogrenci+i)->midterm < 0 || (ogrenci+i)->final > 100 || (ogrenci+i)->final < 0)
    {
        printf("midterm or final can not be higher than 100 or lower than 0 \n");
        exit(1);
    }
}

}

void yazma (int studentnum){

int i;
STUDENT_MARK *ogrenci;
FILE *dosya;
dosya = fopen("marks_190704033.txt","w");
if{ (dosya == NULL)
    {
    printf("Could not open file");
    exit(1); 
    }
else
{

    for(i=0;i<studentnum;i++)
        {
            fprintf(dosya, "%s %s %d %d", (ogrenci+0)->name, (ogrenci+0)- 
>surname, (ogrenci+0)->midterm, (ogrenci+0)->final);
    }


}
fclose(dosya);
}


int main()
{

int n =2;
girme(n);
yazma(n);


return 0;
}
  • `fprintf("error")` is always wrong. Error messages belong on stderr, not stdout. And errors related to `fopen` should include the path that was used and the reason for the failure. eg `if (( f = fopen(path, mode)) == NULL) { perror(path); ...` – William Pursell Apr 17 '20 at 16:41
  • If we assume that ogrenci points to the first member of a properly initialized array, in which all of the members are also properly initialized, then what you have should work. Since what you have doesn't work, your initializations are probably incorrect. – William Pursell Apr 17 '20 at 16:48
  • I hope you're also initializing studentnum to something reasonable. If you don't initialize that value properly, you may get unpredictable results. For instance, if the system initialized that value for you to 0... your loop would never run. – Mike Mytkowski Apr 17 '20 at 16:52
  • What do you mean with _"I attent pointer to struct in a different function."_? You _obtain_ the pointer? You _allocate_ it? You make an _attempt_ to get it? I wasn't able to correct that part. – Roberto Caboni Apr 17 '20 at 16:56
  • I'm guessing that by "I attent pointer to struct in a different function" you meant "I'm setting the pointer-to-struct in a different function". I suspect that this "different function" has a problem and isn't doing its job properly. Please edit your question and include this function as well. Thanks. – Bob Jarvis - Слава Україні Apr 17 '20 at 17:07

1 Answers1

2
STUDENT_MARK *ogrenci;
ogrenci = (STUDENT_MARK*) malloc(studentnum * sizeof(STUDENT_MARK));

ogrenci is a single pointer to the structure STUDENT_MARK to space allocated for several objects of struct STUDENT_MARK.

When using, f.e.:

(ogrenci+i)->name

in the for loop, you attempt to access not existing struct pointers to not existing structure objects.

Note: The compiler do not associate the allocated space with several pointers!


If you want to use pointer arithmetics like (ogrenci + i) you need to either define ogrenci as an array of pointers to STUDENT_MARK:

int studentnum = 5;
STUDENT_MARK *ogrenci[studentnum];            

and initialize each pointer by the address of an existing structure object for which were each allocated space individually, f.e. like:

int studentnum = 5;
STUDENT_MARK *ogrenci[studentnum];

for(int i = 0; i < studentnum; i++)
{
    ogrenci[i] = malloc(sizeof(*ogrenci));
}

or you define ogrenci as a pointer to pointer to STUDENT_MARK:

int studentnum = 5;
STUDENT_MARK **ogrenci;

ogrenci = malloc(sizeof(*ogrenci) * studentnum);
*ogrenci = malloc(sizeof(**ogrenci) * studentnum);

"When writing like this (ogrenci+0) it works correctly."

However, It "works" with 0 because ogrenci + 0 = ogrenci. There is no difference to ogrenci.


Side note: As you mabe have already seen, I omitted the cast of the returned pointer from malloc. This is because it is unnecessary and it might "add clutter" to your code: Do I cast the result of malloc