IS 12 8

IS12 – Introduction to Programming Date: April 9, 2003

Two Dimensional Arrays, Files, and Structs


Two Dimensional Arrays

A two-dimensional array is a table of entries in which we use two subscripts to identifiy the data. These two subscripts include the row and column location. To determine how many locations are available for data entry, multiply the number of rows by the number of columns.

An example declaration of a two dimensional array is as follows:

int x[ 3 ] [ 2 ] = { { 1, 2 }, { 2, 3 }, { 4, 5 } )

The name of the array is x. The table has three rows by two columns. Its content is:

0 1

0 1 2

1 2 3

2 4 5

In the following program, three two dimensional arrays are created with initialization and printing.

#include <stdio.h>

void printArray( const int [][ 3 ] );

int main()

{

int array1[ 2 ][ 3 ] = { { 1, 2, 3 }, { 4, 5, 6 } },

array2[ 2 ][ 3 ] = { 1, 2, 3, 4, 5 },

array3[ 2 ][ 3 ] = { { 1, 2 }, { 4 } };

printf( "Values in array1 by row are:\n" );

printArray( array1 );

printf( "Values in array2 by row are:\n" );

printArray( array2 );

printf( "Values in array3 by row are:\n" );

printArray( array3 );

return 0;

}

void printArray( const int a[][ 3 ] )

{

int i, j;

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

for ( j = 0; j <= 2; j++ )

printf( "%d ", a[ i ][ j ] );

printf( "\n" );

}

}

Passing files to functions

To pass a file to a function, the argument must be defined as a pointer to a FILE. In this program, the user is to enter five lines of text and then the program outputs the information to a file called text.dat via the fprintf function.

#include <stdio.h>

#define LINELEN 81

#define NUMLINES 5

char *file_name = "text.dat";

int main(void)

{

FILE *out_file;

void in_out(FILE *);

out_file = fopen(file_name,"w");

if (out_file == (FILE *) NULL)

{

printf("\nFailed to open the file %s\n", file_name);

return -1;

}

in_out(out_file);

fclose(out_file);

return 0;

}

void in_out(FILE *fname)

{

int count;

char line[LINELEN]; /* enough storage for one line of text */

printf("Please enter five lines of text:\n");

for (count = 0; count < NUMLINES; count++)

{

gets(line);

fprintf(fname,"%s\n",line);

}

return;

}


Files and their functions

The standard libaray #include <stdio.h> has the necessary functions for reading and writing to files. Example functions include:

fopen() opens a file

fclose() closes a file

putc() sends and writes a character to a file

fputc() same as putc()

getc() reads a character from a file

fgetc() same as getc()

fgets() reads a string from a file

fputs() writes a string to a file

fread() transfers a number of bytes from a file via file position setting

fseek() sets the pointer to a given (byte) location in a file

ftell() returns the file position

fprintf() writes to a file (like printf() console) – records may not be fixed length

fscanf() reads from a file (like scanf() to console)

fwrite() transfers and writes a number of bytes to a file

feof() returns true if the end of the file is reached

ferror() returns true if an error occurred

rewind() resets the file indicator back to the beginning of the file

remove() removes a file

Sequential files – see notes from last week

With sequential files, the records are stored one after the other. When retrieving the records, the records are returned one after another, starting at the beginning of the file (unless we need to reread the file via the rewind() function)

Random files

With random files, the records are written in random order to the disk. We can access any record in the file without having to read all prior records stored before it. Sample program to create a random file: The file writes 100 records out with 0’s and blanks. This is for the eventual determination in writing records to a an empty location, due to the random writing of the records.

#include <stdio.h>

struct clientData {

int acctNum;

char lastName[ 15 ];

char firstName[ 10 ];

double balance;

};

int main()

{

int i;

struct clientData blankClient = { 0, "", "", 0.0 };

FILE *cfPtr;

if ( ( cfPtr = fopen( "credit.dat", "w" ) ) == NULL )

printf( "File could not be opened.\n" );

else {

for ( i = 1; i <= 100; i++ )

fwrite( &blankClient,

sizeof( struct clientData ), 1, cfPtr );

fclose ( cfPtr );

}

return 0;

}

Writing information to a random file

In this example program, the records are written to the random file via the fseek function and the fwrite function. The fseek function sets the specific position in the file and the fwrite function writes the information at that location.

#include <stdio.h>

struct clientData {

int acctNum;

char lastName[ 15 ];

char firstName[ 10 ];

double balance;

};

int main()

{

FILE *cfPtr;

struct clientData client = { 0, "", "", 0.0 };

if ( ( cfPtr = fopen( "credit.dat", "r+" ) ) == NULL )

printf( "File could not be opened.\n" );

else {

printf( "Enter account number"

" ( 1 to 100, 0 to end input )\n? " );

scanf( "%d", &client.acctNum );

while ( client.acctNum != 0 ) {

printf( "Enter lastname, firstname, balance\n? " );

fscanf( stdin, "%s%s%lf", client.lastName,

client.firstName, &client.balance );

fseek( cfPtr, ( client.acctNum - 1 ) *

sizeof( struct clientData ), SEEK_SET );

fwrite( &client, sizeof( struct clientData ), 1,

cfPtr );

printf( "Enter account number\n? " );

scanf( "%d", &client.acctNum );

}

fclose( cfPtr );

}

return 0;

}

The following program shows how to read records from a random file. Function fread reads a given number of bytes from the file into computer memory for processing.

#include <stdio.h>

struct clientData {

int acctNum;

char lastName[ 15 ];

char firstName[ 10 ];

double balance;

};

int main()

{

FILE *cfPtr;

struct clientData client = { 0, "", "", 0.0 };

if ( ( cfPtr = fopen( "credit.dat", "r" ) ) == NULL )

printf( "File could not be opened.\n" );

else {

printf( "%-6s%-16s%-11s%10s\n", "Acct", "Last Name",

"First Name", "Balance" );

while ( !feof( cfPtr ) ) {

fread( &client, sizeof( struct clientData ), 1,

cfPtr );

if ( client.acctNum != 0 )

printf( "%-6d%-16s%-11s%10.2f\n",

client.acctNum, client.lastName,

client.firstName, client.balance );

}

fclose( cfPtr );

}

return 0;

}

Structs

Structures are comprised of variables are also called aggregates. Structs can have various datatypes. A sample struct has elements of various data types.

Example:

struct month {

int monthOfYear;

int day;

int year;

};

The name of the structure is month. The structure members include monthOfYear, day, and year. Members of the same struct must have different names; but to different structures may contain members of the same name without an errors or violations. A structure can have a pointer to the same structure. This is known as self-referential structure. This is useful for data structures such as linked lists, queues, stacks, and trees. A struct does not take up any room in memory, only the variables have been defined.

Accessing Members of Structures

Members of a structure are accessed using the member access operators- the dot operator (.) and the arrow -> operator.

#include <stdio.h>

struct card {

char *face;

char *suit;

};

int main()

{

struct card a;

struct card *aPtr;

a.face = "Ace";

a.suit = "Spades";

aPtr = &a;

printf( "%s%s%s\n%s%s%s\n%s%s%s\n",

a.face, " of ", a.suit,

aPtr->face, " of ", aPtr->suit,

( *aPtr ).face, " of ", ( *aPtr ).suit );

return 0;

}

By default, structures are passed as call-by-value. To avoid the copying of a structure, pass the structure as a call-by reference.


References used

Bronson, G. (1996). Algorithm Development and Program Design using C. Minneapolis/St. Paul: West Publishing Company.

Deitel, H., and Deitel, P. (2001). C How to Program, Third Edition. NJ: Prentice Hall.

Schildt, H. (2000). The Complete Reference – C Fourth Edition. CA: Osborne-McGraw-Hill.