0% found this document useful (0 votes)
46 views37 pages

COMS11500: Introduction To C

The document discusses file input/output in C. It covers opening and closing files, file streams, buffers, and functions for reading from and writing to files like fopen(), fclose(), fprintf(), fscanf(), fgets(), and fflush(). The key aspects are managing file streams and pointers, checking for errors, flushing buffers, and using format specifiers correctly with functions like fprintf() and fscanf().

Uploaded by

Rodrigo Silva
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
46 views37 pages

COMS11500: Introduction To C

The document discusses file input/output in C. It covers opening and closing files, file streams, buffers, and functions for reading from and writing to files like fopen(), fclose(), fprintf(), fscanf(), fgets(), and fflush(). The key aspects are managing file streams and pointers, checking for errors, flushing buffers, and using format specifiers correctly with functions like fprintf() and fscanf().

Uploaded by

Rodrigo Silva
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 37

COMS11500: Introduction to C

26 Nov, 2013
In previous lectures

1 Basic operations, e.g. assignments


2 Conditional flow control (if/then/else)
3 Iteration (for/while/do..while loops)
4 Recursion
5 Arrays, pointers and memory management
6 Strings
Problem
Fixing Luhn check digits

Task
Given a file data.in containing integers,
1 read the integers in the file,
2 modify these integers so their Luhn checksum works out,
3 and write the modified integers to data.out
Problem
Fixing Luhn check digits

Task
Given a file data.in containing integers,
1 read the integers in the file,
2 modify these integers so their Luhn checksum works out,
3 and write the modified integers to data.out

Skills needed
How to read from and write to files
How to reuse existing code (e.g. in numbers.cpp) for our own
purposes (i.e. to fix the Luhn checksum)
File input/output

Outline

1 File input/output

2 Managing Large Programs


Code Reuse
Using Header Files
File input/output

Streams and files

Introductory comments
Programs must be able to write data to files or to physical output
devices, such as displays or printers, and to read in data from files or
input devices such as a keyboard.
The C standard library provides numerous functions for these
purposes. The part of the standard library devoted to these
input/output operation is often referred to as the I/O library.
All of the basic functions, macros, and types for input and output are
declared in the header file stdio.h
Apart from these library functions, the C language itself contains no
input or output support at all.
The I/O functionality of C is fairly low-level by modern standards.
File input/output

Streams and files

Streams
From the point of view of a C program, input and output operations,
whether to or from physical devices (e.g. screens and keyboards), or
whether to or from files on storage devices (e.g. hard disks), are
mapped onto logical data streams
A stream can be thought of as a channel, by which data can flow to
the program (input streams), or from the program (output
streams).
The stream model of file I/O was popularized by the Unix operating
system, which was developed concurrently with the C programming
language itself.
According to the type of data transmitted through streams, we can
distinguish between text streams and binary streams.
File input/output

Streams and files

Text streams
A text stream is a sequence of bytes, which are mapped onto ASCII
characters and collectively form human-readable text.
The text is divided into lines, each consisting of zero or more
characters plus a terminating newline character.
Lines can be empty, i.e. they consist of the newline character only.
The last line in the stream may or may not have a newline character,
depending on the implementation.
File input/output

Streams and files

Binary streams
A binary stream is a sequence of bytes without any modification (i.e.
no mapping to ASCII or other type of code is performed).
The data transmitted through a binary stream are not readable by
humans (unlike text streams)
Because no mapping is taking place, operations on binary streams are
generally faster and occupy less space than text streams.
Here, we focus on text streams
File input/output

Streams and files

Standard streams
When a C program starts executing, three standard text streams are
created and they become availble to the program:
Standard input (stdin): usually associated with the keyboard; used by
scanf to read data.
Standard output (stdout): usually associated with the screen; used by
printf to write data.
Standard error (stderr): used for outputing error messages; default
behaviour usually indistinguishable from stdout.
The associations of these streams with devices can be modifed (i.e.
streams can be redirected)
File input/output

Streams and files

Files
A file is a pool of data (bytes), which can be associated with (and
controlled by) a stream
From the point of view of C (and Unix), stored files and devices are
both just files (e.g. disk files and device files), which can be accessed
uniformly through streams.
There are text files and binary files
The association between a file and a stream results in the creation of
a data structure of type FILE (defined in stdio.h).
The programmer uses a pointer to this structure (i.e. FILE *) to
control the stream and read to or write from the file.
The variables stdin, stdout and stderr we saw earlier are actually
pointers to dierent FILE structures!
File input/output

Streams and files


Buers
In working with files, it is generally not ecient to read or write
individual characters.
For this reason, each stream has a buer in which it collects
characters, which are transferred as a block to or from the associated
file
This transfer is known as flushing the buer. Streams can be:
Fully buered: the buer is flushed after it becomes full
Line-buered: the buer is flushed when a newline character is
written to the buer or when the buer is full
Unbuered: characters are written as promtly as possible
Also, buers can be flushed at any point by the programmer, using
appropriate functions.
The buering behaviour and size of the buer for a particular stream
can be changed by the programmer.
File input/output

File Input/Output
An overview

Start

Open

Golden Rules
no
Succeeded? report 1 Test if opening your files was successful
yes
2 Test for terminating conditions (e.g.
read/write
end of file)
no
Done?
3 Do not forget to close your files once
yes
done!
close

End
File input/output

Opening a file
FILE *fopen(char *filename, char *mode);
Declared in <stdio.h>, opens file and links it to a stream
mode is up to 3 characters long, indicates permitted operations:
r read only (returns NULL, if file not found)
w write only (erases file if it exists, creates it otherwise)
a append only (creates file if necessary)
Add a + for both reading and writing, e.g. r+
Add a b for binary files, e.g. rb or r+b.
Always use double-quotes!

Examples (assuming we have already declared, e.g. FILE * fp):


fp = fopen("myfile.txt", "r"); opens file for reading
fp = fopen("myfile.txt", "r+"); opens file for both reading and writing
fp = fopen("myfile.txt", "rb+"); as above, but file is opened as binary
File input/output

Closing a file

int fclose(FILE *fp);


Declared in <stdio.h>
Flushes buer, closes file, releases memory used by associated stream
Returns zero on success, or EOF if an error occurs
fp must point to an already open file

Note:
Upon exit of the program, all buers all flushed and files are closed
If program exits abnormally, you might lose data (because of unflushed
buers)
File input/output

File Input/Output
Some of the available functions

Management
Assuming fp points to an open file
fflush(fp) flushes the buer of the associated stream.
rewind(fp) sets the file position indicator at the beginning of the
file.
Notes about the file position indicator:
indicates you current position within the file
with every read operation, it moves closer to the end of file
at the end of file, it takes the value EOF (check using feof(fp))
use rewind at this point (or earlier), to be able to reread your file
File input/output

File Input/Output
Some of the available functions

Output (writing)
fprintf prints a formatted string to an arbitrary stream.
fputs prints an unformatted string to an arbitrary stream.
fwrite is used primarily for writing data to binary files (well ignore it)

Input (reading)
fscanf reads formatted data from an arbitrary stream.
fgets reads an unformatted string from an arbitrary stream,
avoiding overflows (safer than gets)
fread is used primarily for reading data from binary files (well ignore
it)
File input/output

Using fprintf()

fprintf(FILE *stream, char *format, arg1, ...);


Where format may include two types of special symbols:
Escape Characters such as \n (for newline) or \t (for tab).
Format Specifiers such as %d (for ints) or %e, %g or %f (for
floats).
For each format specifier in format there must be a corresponding
argi (as part of the fprintf command).
The value of argi is supplanted into format in place of the format
specifier.

For example:
Do fprintf(stdout, This is arg1: %f, arg2: %e and arg3: %g\n, 3.14, 3.14, 3.14), or
printf(This is arg1: %f, arg2: %e and arg3: %g\n, 3.14, 3.14, 3.14)
File input/output

Using sprintf()

sprintf(char *str, char *format, arg1, ...);


It works as fprintf, but it prints the output in string str, not in a
file
str should be large enough to hold the resulting string

For example:
Do sprintf(str, This is arg1: %f, arg2: %e and arg3: %g\n, 3.14, 3.14, 3.14),
followed by printf(%s\n, str)
Do you need the newline character in printf? No, porque ya
est en la cadena
str
File input/output

Using fscanf()
int fscanf(FILE *stream, char *format, *arg1, ...);
Reads data from stream according to format and stores them in the
locations pointed to by the pointers argi
Whitespace characters are ignored
Often format consists purely of format specifiers, such as %d for
ints and %f for floats.
The return value indicates the number of successfully parsed items.
Not very user-friendly for reading strings (use fgets, instead).

For example:
Do fscanf(stdin, %d %f %c,&arg1, &arg2, &arg3), where arg1, arg2 and
arg3 are previously defined integer, float and character variables.
The same as scanf(%d %f %c, &arg1, &arg2, &arg3)

Notice that we pass pointers (why?)


File input/output

Using sscanf()
int sscanf(char *str, char *format, *arg1, ...);
This the same as fscanf, but instead of reading data from a stream,
we read from input string str.
For example:
char *str = "I love Julian , 3.14 and Dimitris";
char name1[10], name2[10];
float pi;
sscanf(str, "%*s %*s %s %*s %f %*s %s", name1, &pi, name2);
fprintf(stdout, "%s %s %f", name1, name2, pi);

Notice the %*s format specifiers (what do they do?)


What happens if there is no space between Julian and ,? Can you
make it work?
File input/output

Unformatted I/O

char *fgets(char *str, int num, FILE *stream);


Reads (num-1) characters from stream (or until either a newline or
EOF is reached) and stores them in str
A terminating null character is automatically appended in str.
The str is returned upon success or NULL upon failure
Safe, since it avoid overflows

int fputs(char *str, FILE *stream);


Writes str to stream, up to (but not including) the terminating null
character
If constructing str manually, dont forget to include the terminating
null character!
File input/output

Writing Files
Some subtleties

Two Nice Tricks


1 How do I create empty files?
2 How do I avoid overwriting an existing file?
File input/output

Writing Files
Some subtleties

Two Nice Tricks


1 How do I create empty files?
2 How do I avoid overwriting an existing file?

Writing empty files


Just open for writing and, then, close.

FILE *fp;
fp = fopen("myfile.txt", "w");
fclose(fp); // now "myfile.txt" is an empty file
File input/output

Writing Files
Some subtleties

Two Nice Tricks


1 How do I create empty files?
2 How do I avoid overwriting an existing file?

Writing empty files


Just open for writing and, then, close.

FILE *fp;
fp = fopen("myfile.txt", "w");
fclose(fp); // now "myfile.txt" is an empty file
remove("myfile.txt"); // deletes the file
File input/output

Writing Files
Some subtleties

Two Nice Tricks


1 How do I create empty files?
2 How do I avoid overwriting an existing file?

Avoid overwriting existing files


Just open file for reading and check if returned pointer is NULL.

FILE *fp;
fp = fopen("myfile.txt", "r");
{check whether fp is NULL and act accordingly}
fclose(fp);
File input/output

File Input/Output
An overview

Start

Open
Golden Rules
Succeeded?
no
report
1 Test if opening your files was successful
yes
(NULL)
read/write 2 Test for terminating conditions (e.g.
EOF)
no
Done? 3 Do not forget to close your files once
yes
done!
close

End
Managing Large Programs

Outline

1 File input/output

2 Managing Large Programs


Code Reuse
Using Header Files
Managing Large Programs Code Reuse

Reusing Existing Code


Practical approaches

Dierent ways to recycle code


1 Wholesale or as is:
you simply use (call) the functions as they are. All you need to know
are function prototype and (intended) behaviour. Seldom need to
know internals.
2 Minor modifications:
for instance you change from double exponentiation to modular
exponentiation. Need to know what is going on, at least superficially.
3 Major modifications:
use chunks of codes, but heavily garbled up. Need to be able to isolate
and understand interesting parts of the original.
4 For inspiration:
you look at the code, understand what it is doing, and then only use
the underlying ideas.
Managing Large Programs Code Reuse

Reusing Existing Code


Ethical Side

Beware when using other peoples code


1 Do you have permission?
Perhaps the code is proprietary,
Possibly you would need to pay a fee.
Some code can be used, but not modified.
Adapting open source code might impose open source to you.
2 Do you give proper credit?
Passing of other peoples code or ideas as your own is plagiarism.
3 Expect to be liable for flaws in the end product, even if the bugs might
originate elsewhere.
Managing Large Programs Code Reuse

Reusing Existing Code


Ethical Side

Reusing code from the COMS11500 website


Chunks of code from the website can be used freely in your coursework,
provided that you give proper credit.
There is no penalty for extensive, declared use of code from the
COMS11500 website (it will not stop you from getting full marks).
If you copy code from the COMS11500 website into your program
without explicit mention, we will consider this bad style and can
deduct points accordingly.
Undeclared copying from the COMS11500 website will not be
considered plagiarism.
Managing Large Programs Code Reuse

Reusing Existing Code


Ethical Side

Part C of CW4
Here you will need to use numbers.cpp and numbers.h. Since you use
these files as is, you only need to include the header file (without further
explanation).
Managing Large Programs Using Header Files

Using header files


Splitting a Project into Multiple Files

/* main.cpp */
#include <stdio.h>
#include <stdlib.h>

/* function declarations */
int myfcn1(char *str);
void myfcn2(int var);

/* main function*/
int main (void)
{
/* use myfcn1 and myfcn2, here */
}

/* function definitions */
int myfcn1(char *str)
{
/* stuff goes here */
}

void myfcn2(int var)


{
/* stuff goes here */
}
Managing Large Programs Using Header Files

Using header files


Splitting a Project into Multiple Files

/* myfunctions.h */
#include <stdlib.h>
#include <stdio.h>

int myfcn1(char *str);


/* Explanation of what */

/* main.cpp */ void myfcn2(int var);


#include <stdio.h> /* Explanation of what */
#include <stdlib.h>
#include "myfunctions.h"

/* main */ /* myfunctions.cpp */
int main (void) #include "myfunctions.h"
{
/* use myfcn1 and myfcn2, here */ int myfcn1(char *str)
} {
/* stuff goes here */
}

void myfcn2(int var)


{
/* stuff goes here */
}
Managing Large Programs Using Header Files

The Luhn Checksum

Also known as the Luhn formula, or mod 10 algorithm


Created by IBM scientist Hans Peter Luhn in the 50s
A simple, widelyused formula for validating small strings of data,
such as credit card numbers
Checksum: a calculation over a set of digital data, which helps detect
errors introduced during the transmission and storage of this data
Check digit: a checksum in the form of a single digit, which is
appended at the end of the data string
Given a string of digits (an , . . . , a0 ), where a0 is the check digit,
compute: 0 n 1
d2e b n2 c
X X
error = @ 2a2i 1 + a2i A mod 10
i=1 i=0
Managing Large Programs Using Header Files

The Luhn Checksum


Splitting the project into multiple files

/* main.cpp */
#include <stdio.h>
#include <stdlib.h>
#include "numbers.h"

/* main function*/
int main (void)
{
/* use luhncheck() here */
}

/* numbers.h */
#include <stdio.h>
#include <stdlib.h>

int luhncheck(const int *cardnumber, int size_of_number);


/* Returns the error in the check digit of cardnumber
* according to Luhns algorithm and assuming that cardnumber
* is an array of size_of_number digits with cardnumber[0] being
* the check digit.
* luhncheck does not check if the elements in cardnumber
* are indeed ints representing digits.
*/
Managing Large Programs Using Header Files

The Luhn Checksum


Listing of numbers.cpp

#include "numbers.h"

int luhncheck(const int *cardnumber, int size_of_number)


{
int i=0;
int checksum=0;

while (i < size_of_number)


{
if (i % 2 == 0)
{
checksum -= cardnumber[i];
} else {
checksum -= 2*cardnumber[i];
}
checksum %= 10;
i++;
}

return checksum;
}

You might also like