Thread: Problem with passing structure array to function prototype

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    12

    Question Problem with passing structure array to function prototype

    Sorry to bother you all again. You all seem like experts next to me, so I thought I'd pick your brains. I'm fairly clueless when it comes to pointers, and I'm sure I've made quite a few rookie mistakes. I'm facing 3 problems with this code:

    1. First and foremost, it doesn't appear that I'm correctly passing or referencing the pointers. The read_student printf is returning gibberish, and the main printf is returning even worse gibberish.

    2. The call to read_student only seems to work on the first loop. After that, neither of the printfs in read_student print on each loop.

    3. The read_student printf counter is initially printing 50 times, yet there is only 25 lines of text to read. There's only a single '\n' at the end of each line. This suggests that the fgets is reading 50 lines, but I don't see how.

    Code:
    #include <stdio.h>
    #include <string.h>
    
    #define STUDENT_FILE "student.txt"
    
    FILE *textin;
    
    int highestMark, counter, lineCounter, nullCounter, i, j;
    char line[64];
    
    struct student {
    	char id[9];
    	int paperOne;
    	int paperTwo;
    	int paperThree;
    	int paperFour;
    	int paperFive;
    	int paperSix;
    	int paperSeven;
    	int paperEight;
    };
    
    void read_student(struct student *);
    void print_student(struct student *);
    void copy(int *x, char *y, char *z);
    
    int main() {
    	textin = fopen(STUDENT_FILE, "r");
    	struct student grades[25];
    	lineCounter = 0;
    	for (i=0; i<25; i++) {
    		read_student(&grades[i]);
    	/*	printf("%s\n", grades[i].id);
    		print_student(*pGrades[i]); */
    		printf("Main counter: %i\n", lineCounter);  /* for testing */
    		printf("Printf main: %s\n", grades[i].id);	/* for testing */
    		lineCounter++;
    		rewind(textin);
    	}
    	fclose(textin);
    }
    
    void read_student(struct student *grades) {
    	counter = 0;
    	while (fgets(line, 65, textin) != NULL) {
    		if (counter == lineCounter) {
    			sscanf(line, "%s %d %d %d %d %d %d %d %d", grades->id, &grades->paperOne, &grades->paperTwo, 
    			&grades->paperThree, &grades->paperFour, &grades->paperFive, &grades->paperSix, &grades->paperSeven, 
    			&grades->paperEight);
    		}
    		if (line[0] != '\n') {
    			counter++;
    		}
    	}
    }
    EDIT: Solved problem 2 by placing a rewind(textin) in the main loop.

    EDIT2: Solved. I had to add a check for the return character '\n' on its own line. fgets was reading end of line at \r, then promptly reading end of line again at the \n. I've uploaded the fix and the current build in case anyone else gets stuck in a similar situation. Thanks to everyone who lent a hand.
    Last edited by Gareth321; 05-29-2011 at 11:51 PM.

  2. #2
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    C doesn't know how to copy arrays across the = sign... For strings you can use strcpy() for arrays of ints etc. you need to write a function to copy the array.

    Code:
    grades->id[j] = line[j];  <--- line is a char array... this won't work.
    To convert the values on your read-in string, use sscanf().

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    12
    Thanks Tater.

    For copying the array of int, do you mean another function prototype? Something like:

    Code:
    edited:
    void copy(int *x, char *y, char *z) {
    	tempInt = *y - 48;
    	tempIntTwo = *z - 48;
    	*x = tempChar + tempCharTwo;
    }
    As for using sscanf, I've removed the 8 count loop, and replaced it with:

    Code:
    sscanf(line, "%s", grades->id);
    Last edited by Gareth321; 05-29-2011 at 10:04 PM.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Gareth321 View Post
    Thanks Tater.

    For copying the array of int, do you mean another function prototype? Something like:

    Code:
    void copy(int *x, char *y, char *z) {
    	tempChar = *y;
    	tempCharTwo = *z;
    	*x = ((tempChar - 30) * 10) + (tempCharTwo - 30);
    }
    As for using sscanf, I've removed the 8 count loop, and replaced it with:

    Code:
    sscanf(line, "%s", grades->id);
    I'm thinking you need to get busy with a good tutorial on arrays...

    Can you pust a few lines of the file you're trying to read... That might help...

  5. #5
    Registered User
    Join Date
    May 2011
    Posts
    12
    Haha, yes. I've been stuck into array and pointer tutorials for about a day now, but some of it is lost on me.

    Here is the file I'm trying to read:

    Code:
    41018467     74     80     69     44     58     58     62     84
    05028145     41     67     41     51     95     42     67     76
    91014604     42     73     92     62     61     96     78     75
    47021726     51     58     49     92     87     59     95     94
    03023811     42     73     73     84     61     71     93     68
    47027644     62     97     97     59     63     61     89     94
    16003035     90     82     88     86     80     42     44     68
    46023805     90     49     50     90     46     61     73     48
    29012623     64     74     76     60     86     96     51     68
    44032439     66     83     57     93     78     82     49     81
    33031115     59     58     64     70     97     66     93     46
    21028745     84     92     70     49     57     73     97     52
    86013290     81     76     75     87     55     74     51     92
    50001150     61     44     86     50     67     51     47     97
    57012287     73     43     45     69     89     78     81     88
    22024946     66     50     73     48     40     51     82     75
    10006359     64     57     48     43     95     61     42     90
    91030836     54     80     76     61     88     79     88     44
    81004734     93     59     58     78     40     48     47     87
    28014893     88     83     87     61     70     57     53     74
    09007616     75     91     60     69     59     96     95     43
    24011008     64     69     89     42     55     65     73     43
    23001587     74     63     48     40     58     58     40     96
    98015281     69     78     89     77     52     82     96     98
    38024179     50     57     78     51     55     68     56     91
    Last edited by Gareth321; 05-29-2011 at 10:05 PM.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Ok... not being certain what each column represents you could do something like this...

    Code:
    struct tStudents
      { int id;
         int mark[8];
       } student[100];
    
    
    idx = 0;
    while (fgets(line, 64, textin) != NULL) {
      sscanf(" %d %d %d %d %d %d %d %d %d", student[idx].id,
                     student[idx].mark[0],student[idx].mark[1],student[idx].mark[2],student[idx].mark[3],
                     student[idx].mark[4],student[idx].mark[5],student[idx].mark[6],student[idx].mark[7]);	
       ++idx; 
    }
    A complication may come if those are tabs instead of spaces between columns... then it becomes sscanf("%d\t%d\t...
    Also if the array gets too big, or you have an unknown number of students you may need to typedef the struct and use malloc() and realloc() to get the space you need.
    Last edited by CommonTater; 05-29-2011 at 10:26 PM.

  7. #7
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Code:
    41018467
    
    	char id[8];
    Count carefully. and don't forget that C string needs 1 more room for '\0' character which signals end of string.
    Since you're reading from formatted file, just use fscanf(). and check return value. Read the doc!

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by CommonTater View Post
    A complication may come if those are tabs instead of spaces between columns... then it becomes sscanf("%d\t%d\t...
    Technically, I should complain about this, because scanf doesn't know the difference between a space, a tab, a newline, and a formfeed. But I won't, because I also believe that you shouldn't lie to scanf, and if nothing else it's documentation for you (or your teacher, or whomever) as to what the file format actually is.

    Admittedly I would also put the reading of the marks in an inner loop anyway (and skip the intermediate string read), but of course that makes it a bit more brittle.

  9. #9
    Registered User
    Join Date
    May 2011
    Posts
    12
    Thanks very much, Tater. I've implemented your sscanf suggestion (edit in first post) and it's actually passing the data back to int main() now. Unfortunately I still have to use the void function, as it's part of the requested specifications. I'm still having problems with the function returning gibberish, but only on every second loop.
    Last edited by Gareth321; 05-29-2011 at 11:02 PM.

  10. #10
    Registered User
    Join Date
    May 2011
    Posts
    12
    Quote Originally Posted by Bayint Naung View Post
    Code:
    41018467
    
    	char id[8];
    Count carefully!
    You're a champ I'll give fscanf a go. I've been told a few times to always use fgets if possible.

  11. #11
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Gareth321 View Post
    Thanks very much, Tater. I've implemented your sscanf suggestion (edit in first post) and it's actually passing the data back to int main() now. Unfortunately I still have to use the void function, as it's part of the requested specifications. I'm still having problems with the function returning gibberish, but only on every second loop.
    Now ... PLEASE stop editing your first message. For anyone else who comes through this thread looking for help, the original problem is no longer in evidence and it makes the remaining discussion useless to them...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 07-15-2010, 09:14 AM
  2. Problem Passing Structure Reference To Function
    By soj0mq3 in forum C Programming
    Replies: 9
    Last Post: 04-24-2010, 10:27 AM
  3. function prototype with array
    By melodia in forum C Programming
    Replies: 3
    Last Post: 11-15-2009, 02:31 PM
  4. passing array to function problem
    By thestien in forum C++ Programming
    Replies: 13
    Last Post: 05-10-2008, 01:45 AM
  5. Replies: 6
    Last Post: 02-15-2005, 11:20 PM