5 Replies - 696 Views - Last Post: 03 April 2013 - 12:52 PM Rate Topic: -----

#1 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Passing array of structs to a function for modification

Posted 03 April 2013 - 08:33 AM

I have an array of structs that hold state abbreviations.

I have a function to test for a valid abbreviation. If the array is empty, I want to send it to a load function to load the data from a text file. I need the table to stay populated so I can use my validState function repeatedly.

Here is my struct I declared it above main so both functions have access to it:

struct state
	{
		char abbrev[3];
	};


Here is my getState function.
/*********************************
* Gets state  *
*********************************/
void getState()
{
	char state[3];
	getString("Please enter the state as a 2 character abbreviation:",state);


}//END GETSTATE


And here is my validState function.. it is not complete, I am trying to get the table ready before I move on.

bool validState(char testState[])
{
	static state stateTable[50];
	bool validState = false;

	if (stateTable[0].abbrev[0] == '\0');
		loadStates(stateTable);

	for(int x = 0; x < 50; x++)
	{
		if(!strcmp(testState, stateTable[x]))
			validState = true;
	}

	return validState;
}//END VALIDSTATEE


and finally, here is loadState:

/*********************************
* Load State Table *
*********************************/
void loadStates(struct state stateTable[])
{
	FILE *stateFile;
	char buffer[40];

	stateFile = fopen("STATES.DAT", "r");

	if(stateFile != NULL)
	{
		for(int x = 0; x < 50; x++)
		{
			fgets(buffer, 40, stateFile);
			fgets(buffer, 40, stateFile);
			strcpy(stateTable[x].abbrev, buffer);

			printf(stateTable[x].abbrev);
		}
	}

	fclose(stateFile);
}//ENDLOAD



I am using 2 fgets because the file is formatted this way:

ALASKA
AK
ALABAMA
AL
And I only need the abbreviation. I get the following error when I try to run it:

Error 6 error C2664: 'loadStates' : cannot convert parameter 1 from 'state [50]' to 'state *[]'

This post has been edited by synlight: 03 April 2013 - 08:41 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Passing array of structs to a function for modification

#2 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Passing array of structs to a function for modification

Posted 03 April 2013 - 08:57 AM

Bah I'm an idiot.

I should have been using a plain old array the whole time. Sorry!
Was This Post Helpful? 0
  • +
  • -

#3 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6058
  • View blog
  • Posts: 23,496
  • Joined: 23-August 08

Re: Passing array of structs to a function for modification

Posted 03 April 2013 - 09:28 AM

Can you show us how your getString function is implemented?
Was This Post Helpful? 0
  • +
  • -

#4 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Passing array of structs to a function for modification

Posted 03 April 2013 - 11:47 AM

Here is my getString function:

void getString(char prompt[], char buffer[], int max)
{
	printf("\n%s",prompt);
	fgets(buffer,max,stdin);

}//END GETSTRING

Was This Post Helpful? 0
  • +
  • -

#5 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6058
  • View blog
  • Posts: 23,496
  • Joined: 23-August 08

Re: Passing array of structs to a function for modification

Posted 03 April 2013 - 12:49 PM

OK, that looks pretty better than I expected, but when you showed the call, you were missing the last argument, the max value:

 getString("Please enter the state as a 2 character abbreviation:",state);


This is a better implementation of the function:

void getString(const char *prompt, char buffer[], const int max)
{
    printf("\n%s: ", prompt); // added colon and space for clarity
    if (fgets(buffer, max, stdin) != null) // make sure the fgets succeeds
    {
        // You may need to remove the newline that fgets leaves in the buffer.
        // You can do this by getting the string length and subtracting 1, then
        // checking to see if that character is the newline character, and if it is, 
        // setting that character to the null character, '\0'.
        // For example, if you enter CA into the state buffer, and the buffer is 
        // longer than 3 characters, your array in memory looks like this after the fgets:
        //
        // ---------------------------
        // | 'C' | 'A' | '\n' | '\0' |
        // ---------------------------
        //
        //    0     1      2      3     <-- array index

        // Now because the string length excludes the terminating null character, this will show a 
        // strlen of 3, which means
        char endOfString = buffer[strlen(buffer)];

        // will contain '\0'. Not very useful this case so instead we'll subtract 1 from the strlen
        char maybeNewLine = buffer[strlen(buffer) - 1];

        // And see if it's a newline
        if (maybeNewLine == '\n')
        {
            // It's a new line, so replace the newline with a '\0'
            buffer[strlen(buffer) - 1] = '\0';
        } 
    }
}


Now that's not very efficient, but it demonstrates how it works.

However, users -- often being jerks -- can type in many more characters that you were expecting. These characters will remain in the input buffer, stuffing up later attempts at reading from it, unless you remove them. Here's how you can do this:

void getString(const char *prompt, char buffer[], const int max)
{
    printf("\n%s: ", prompt); // added colon and space for clarity
    if (fgets(buffer, max, stdin) != null) // make sure the fgets succeeds
    {
        // You may need to remove the newline that fgets leaves in the buffer.
        // You can do this by getting the string length and subtracting 1, then
        // checking to see if that character is the newline character, and if it is, 
        // setting that character to the null character, '\0'.
        // For example, if you enter CA into the state buffer, and the buffer is 
        // longer than 3 characters, your array in memory looks like this after the fgets:
        //
        // ---------------------------
        // | 'C' | 'A' | '\n' | '\0' |
        // ---------------------------
        //
        //    0     1      2      3     <-- array index

        // Now because the string length excludes the terminating null character, this will show a 
        // strlen of 3, which means
        char endOfString = buffer[strlen(buffer)];

        // will contain '\0'. Not very useful this case so instead we'll subtract 1 from the strlen
        char maybeNewLine = buffer[strlen(buffer) - 1];

        // And see if it's a newline
        if (maybeNewLine == '\n')
        {
            // It's a new line, so replace the newline with a '\0'
            buffer[strlen(buffer) - 1] = '\0';
        }
        else
        {
            // User entered more than 2 characters, so we need to clear out the input buffer
            int c;
            // Make a loop that does nothing more than consume characters from the input buffer
            // until we encounter the newline the user pressed after the input.
            while ((c = getchar()) != '\n') ;
        }
    }
}


Another demo of C I/O

And there's a big old problem with this:

/*********************************
* Gets state  *
*********************************/
void getState()
{
	char state[3];
	getString("Please enter the state as a 2 character abbreviation:",state);


}//END GETSTATE



When you leave that function, the state variable ceases to exist. You can't use it outside of that function.

Have you read the function tutorials in my signature?
Was This Post Helpful? 0
  • +
  • -

#6 synlight  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 89
  • View blog
  • Posts: 582
  • Joined: 14-September 11

Re: Passing array of structs to a function for modification

Posted 03 April 2013 - 12:52 PM

Well crap.. that explains why my validState wasn't working.

I have actually read your tutorials, they're awesome!

I am in a huggge time crunch to get this program done so I can graduate on time.. but when I get through it I intend to come back and read more. I get all panic-y, and forget everything I know.

EDIT - yes, originally I wasn;t limiting the size of the buffer when I called getString.. with the help of some of the guys here I learned that I should be doing that LOL

This post has been edited by synlight: 03 April 2013 - 12:52 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1