2

Firstly, I'll admit I'm new to this (first year programming, be gentle!). I would hugely appreciate help! I've been trying to find an answer for this problem, but my understanding of pointers and their relationship to opening files is somewhat grey.

Description of issue:

I wish to read a bunch of names (as an array of chars) from a file and store them in an array. I had this working before, but now I want to fill my array with names in a different function called get_names(), while handling the file opening in my main().

My code so far:

   #include "stdafx.h"
   #include <string.h>
   #include <math.h>

   typedef struct {         // Custom data type for holding player information
    char    name[30];       // Name of Player
    int     overs,          // No. of overs
            maidens,        // No. of Maidens
            runs,           // No. of runs scored
            wickets;        // No. of wickets scored
   } member_t;

   /* Function Prototypes */
   void get_names(member_t allplayers[], FILE *input);

   /* Function: To get names from file and place them in allplayers[] array */
   void get_names(member_t allplayers[], FILE *input)
   {
       member_t current_player; // Current player being read from file 
       int      input_status;   // Status value returned by fscanf
       int      i = 0;

    input_status = fscanf(input, "%s", &current_player.name); /////ISSUE HERE??

    while (input_status != -1)
    {
        strcpy(allplayers[i].name, current_player.name);
        allplayers[i].overs = 0;
        allplayers[i].maidens = 0;
        allplayers[i].runs = 0;
        allplayers[i].wickets = 0;

        input_status = fscanf(input, "%s", &current_player.name);
        i += 1;
    }
    }

/* Main Function */
int
main(void)
{
    FILE    *fileinput_a;   // Pointer to file input2a.dat for names
    int     i;

    member_t allplayers[15];

    fileinput_a = fopen("F:\\input2a.dat", "r");    // Opens file for reading
    if (!fileinput_a)                               // Checks to see if file has any data
        printf("File open error - File is empty");  // Empty file error 

    get_names(&allplayers[15], fileinput_a);        // Send array as an output, and file pointer as input

    for (i = 0; i < 15; i++)
    {
        printf("%10s    ", allplayers[i].name);
        printf("%d  ", allplayers[i].overs);
        printf("%d  ", allplayers[i].maidens);
        printf("%d  ", allplayers[i].runs);
        printf("%d\n", allplayers[i].wickets);
    }

    fclose(fileinput_a);

    return(0);
}

Visual Studio 2013 doesn't seem to have an issue with the code, however once it gets up to the marked fscanf function, it throws an Access Violation at me when debugging.

6
  • 2
    get_names(&allplayers[15], fileinput_a); What are you trying to do here, because it sure does not look right. Commented Oct 3, 2014 at 1:30
  • Still getting the hang of indenting! Also, I think that curly bracket is the close bracket for get_names(). The previous one is closing my while loop. It must have gotten moved when I copied it from my program. Commented Oct 3, 2014 at 1:30
  • 1
    You test the file pointer, but your print statement doesn't end with a newline so you may not see the message, and you definitely continue as if it was all OK. It might not be OK. Add a return(1); after (and braces around) after the printf("File open error...\n"); statement. Commented Oct 3, 2014 at 1:31
  • OldProgrammer - I want to send my array of 15 blank players to my function to be "filled" from the file. My understanding is that the '&' allows it to be used as an output from the function. fileinput_a is my pointer to the open file. Commented Oct 3, 2014 at 1:32
  • 1
    As the (other) @OldProgrammer pointed out, you should not be passing the address of the member_t one beyond the end of the array to your function. &allplayers[0] or just allplayers would be OK. Commented Oct 3, 2014 at 1:33

1 Answer 1

1

You have a number of problems:

  1. input_status = fscanf(input, "%s", &current_player.name); should be input_status = fscanf(input, "%s", current_player.name); in both places. current_player.name already decays to a pointer.

  2. get_names(&allplayers[15], fileinput_a); should be get_names(allplayers, fileinput_a);, since passing the address of one element past the end of the array makes no sense.

  3. while (input_status != -1) should be while (input_status && input_status != EOF) since fscanf() can also legitimately return zero rather than EOF, and you should not count on EOF being equal to -1.

  4. As mentioned in the comments, you don't exit if your check on successful file opening fails, which you should.

Updated code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char name[30];
    int overs;
    int maidens;
    int runs;
    int wickets;
}  member_t;

 /* Function: To get names from file and place them in allplayers[] array */
void get_names(member_t allplayers[], FILE * input) {
    member_t current_player;
    int input_status;
    int i = 0;

    input_status = fscanf(input, "%s", current_player.name);

    while (input_status && input_status != EOF) {
        strcpy(allplayers[i].name, current_player.name);
        allplayers[i].overs = 0;
        allplayers[i].maidens = 0;
        allplayers[i].runs = 0;
        allplayers[i].wickets = 0;

        input_status = fscanf(input, "%s", current_player.name);
        i += 1;
    }
}

/* Main Function */
int main(void) {
    FILE *fileinput_a;
    int i;
    member_t allplayers[15];

    fileinput_a = fopen("crickdat", "r");
    if (!fileinput_a) {
        printf("File open error - File is empty");
        return EXIT_FAILURE;
    }

    get_names(allplayers, fileinput_a);

    for (i = 0; i < 15; i++) {
        printf("%10s    ", allplayers[i].name);
        printf("%d  ", allplayers[i].overs);
        printf("%d  ", allplayers[i].maidens);
        printf("%d  ", allplayers[i].runs);
        printf("%d\n", allplayers[i].wickets);
    }

    fclose(fileinput_a);
    return 0;
}

when run on the file crickdat:

walker
simpson
derrick
parker
phillips
dawson
fiddler
wharton
inglis
farquah
finnegan
dobson
wrangler
gaston
brankle

gives the output:

paul@local:~/Documents/src/sandbox$ ./cricket
    walker    0  0  0  0
   simpson    0  0  0  0
   derrick    0  0  0  0
    parker    0  0  0  0
  phillips    0  0  0  0
    dawson    0  0  0  0
   fiddler    0  0  0  0
   wharton    0  0  0  0
    inglis    0  0  0  0
   farquah    0  0  0  0
  finnegan    0  0  0  0
    dobson    0  0  0  0
  wrangler    0  0  0  0
    gaston    0  0  0  0
   brankle    0  0  0  0
paul@local:~/Documents/src/sandbox$ 
Sign up to request clarification or add additional context in comments.

1 Comment

Paul - Thanks! It seems to work a charm now. I'm going through the code to find where I had the mistake... I swear I'd made the suggested changes and it still didn't work, whereas this one seems to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.