Reading an existing file of student names and passwords

In order to create a password file for students, so that they can log on and verify their identity, we need to be able to read and write files (assume that we are willing to create new files ourselves using an editor). As usual, we start with the simplest, and add more, complicating sequentially.
#!/usr/local/bin/perl -- -*- C -*-
# this is 'read_students.pl'
#last_name+first_name+password, where '+' is the delimter
$filename = "students_fall_96.dat";
open ( STUD_FILE , $filename) ;
$i = 0;
	while(<STUD_FILE>){
	chop;#we are here assuming that there will be a carriage return
#		at the end of each line, i.e., that we create the file using
#		an editor.
#		We may need to change this, since we can use students to
#		self-register.
	$single_student[$i] = $_;
	$p1 = index($single_student[$i],'+');
	$last_name[$i] = substr($single_student[$i],0,$p1-1);
	$p2 = index($single_student[$i],'+',p1+1);
	$first_name[$i] = substr($single_student[$i],$p1+1,$p2-1);
	$password[$i] = substr($single_student[$i],$p2+1);
	print "first_name = ",$first_name[$i],"
";
	$i = $i + 1;
	};
close (STUD_FILE);
#!/usr/local/bin/perl -- -*- C -*-
# this is 'read_students.pl'
#last_name+first_name+password, where '+' is the delimter
$filename = "students_fall_96.dat";
open ( STUD_FILE , $filename) ;
The line
open (STUD_FILE , $filename) ;
is the first new piece of coding. `STUD_FILE' is called a file handle. It is an internal way of referring to a file, regardless of its external name. The open statement associates a file handle with an actual file, specifically the file named `$filename' which itself has been set to the string value `students_fall_96.dat', which is the name of a file we have chosen. Before we begin, we intialize a student counter:
$i = 0;

The following few lines are quite peculiar, since Perl takes over lots of the gory details of reading files. Instead, the following construction:
$i = 0;
	while(<STUD_FILE>){
along with the closing `}' will read, one line at a time, the file whose file handle is STUD_FILE.
	chop;#we are here assuming that there will be a carriage return
#		at the end of each line, i.e., that we create the file using
#		an editor.
#		We may need to change this, since we can use students to
#		self-register.
chop is another Perl peculiarity, which takes the line which was just read in and removes the last character. Very often (as in our case) the last character is a carriage return `\n'.
Each line from the open file is placed in the temporary Perl variable `\$_'. Before `chop' that line had a `\n' character at its end, after `chop' it doesn't.
	$single_student[$i] = $_;
`$single_student[]' is a vector quantity, i.e. we are allowed to assign values to `$single_student[0]', `$single_student[1]', `$single_student[2]', etc., etc., etc.. In our case, since on the first read $i is 1 (one), the first line read is assigned to `$single_student[0]'. Before we read another line of the file, we will need to increment `$i'. But, first, we need to process each line read form the external file. First, we extract the three elements, `$last_name[]', `$first_name[]', and this student's password, `$password[]'. So far, we are not going to do anything with this information, but the exercise is just to extract the information, not use it.
	$p1 = index($single_student[$i],'+');
First, we locate the position of the `+' sign, and place this location in the variable `$p1'.
	$last_name[$i] = substr($single_student[$i],0,$p1-1);
Next, we take the characters from 0 to $p1-1 and places them (a substr(ing)) into `$last_name[]'. The first character of a string is at location zero (0), and we do not want to include the `+' sign in the student's last name, hence
substr(from_string,starting location,ending location);
creates a sub string of the `from_string' of a length chosen by us, starting at a position chosen by us.
	$p2 = index($single_student[$i],'+',p1+1);
	$first_name[$i] = substr($single_student[$i],$p1+1,$p2-1);
	$password[$i] = substr($single_student[$i],$p2+1);
These last three lines locate the second plus sign, create the first name, and then create the password.
	print "first_name = ",$first_name[$i],"
";
	$i = $i + 1;
As promised, we increment the variable `$i', so that if it was one, it is now two, if it was 12 then it is now 13.
	};
close (STUD_FILE);
The last `}' closes the reading loop. When the while statement fails, i.e., there are no more lines to read, then we exit the while loop, and close the file.
Click here to test this code
Notice that the output appears on one line. Notice that the last line contains nothing. This is because the file only contains two students, but the program prints three times. Why?
In the next sample, we alter two lines to clean up the program slightly. Thus, we only print a student name if it exists, and we increment using a C-type shorthand (which is acceptable Perl).
#!/usr/local/bin/perl -- -*- C -*-
# this is 'read_students.pl'
#last_name+first_name+password, where '+' is the delimter
$filename = "students_fall_96.dat";
open ( STUD_FILE , $filename) ;
$i = 0;
	while(<STUD_FILE>){
	chop;#we are here assuming that there will be a carriage return
#		at the end of each line, i.e., that we create the file using
#		an editor.
#		We may need to change this, since we can use students to
#		self-register.
	$single_student[$i] = $_;
	$p1 = index($single_student[$i],'+');
	$last_name[$i] = substr($single_student[$i],0,$p1-1);
	$p2 = index($single_student[$i],'+',p1+1);
	$first_name[$i] = substr($single_student[$i],$p1+1,$p2-1);
	$password[$i] = substr($single_student[$i],$p2+1);
#change from first, to print only if there is a name:
	if($first_name[$i] ne ''){print "first_name = ",$first_name[$i],"
";}
#change from first, simplified incrementing:
	$i++;
	};
close (STUD_FILE);
Before we leave this topic, notice that the student_file, $filename = "students_fall_96.dat" was typed in (by me) by hand. Notice also that in typing it, I ended each line with a Return (CR=\n). This is the file:
stalin+joseph+0659w
breznev+leonid+4ofre

The chop then is necessary, for otherwise the password field, which is all the characters beyond $p2+1 would terminate with a carriage return, '\n'.
Click here to test this code

Perl provides a simpler scheme for parsing the password file, i.e., retrieving the individual parts of the file. The ``split'' function provides the functionality required, parsing the string according to the delimeter (``+'' in our case), and assigning each element to an array element, starting at zero. We then assigns these array items to their individual variables.

#!/usr/local/bin/perl -- -*- C -*-
#last_name+first_name+password, where '+' is the delimter
$filename = "students_fall_96.dat";
open ( STUD_FILE , $filename) ;
$i = 0;
	while(){
	chop;#we are here assuming that there will be a carriage return
#		at the end of each line, i.e., that we create the file using
#		an editor.
	@single_student = split(/\+/);
	$last_name[$i] = @single_student[0];
	$first_name[$i] = @single_student[1];
	$pasword[$i] = @single_student[2];
	if($first_name[$i] ne ''){print "first_name [$i] = ",$first_name[$i],"
";}
	$i++;
	};
close (STUD_FILE);

Click here to test this code

Notice the split command, i.e.,
	@single_student = split(/\+/);
and notice the `\+' construction. This will be explained later, when we consider regular expressions, but for the time being, you should note that there are certain characters, call them x, in the form (/x/) which are special, and need to be learned with caution. The string from one slash to the next is called a regular expression, and a study of this kind of expression will take a bit of extra work later. Suffice it to say the (/+/) will not work, and (/\+/) will. The ``\'' character is called an escape character. It tells the operating system that the next character is to be taken literally, i.e., not interpreted at all!

Last revision/editing, July 22, 1997