Lecture09: 5/16/2012 Global Variables, File I/O, and Variable-Length Arguments

advertisement
Lecture09: Global Variables, File I/O,
and Variable-Length Arguments
5/16/2012
Slides modified from Yin Lou, Cornell CS2022: Introduction to C
1
Administration
• Assignment #8 is on the course homepage and due 5/23.
2
Four Items
•
•
•
•
Global vs. local variables
File I/O
<ctype.h>
Variable length arguments
3
Local vs. Global Variables
• The scope of a declaration is the block of code where the
variable is valid for use.
• A global variable(declaration) is outside the main program.
– Normally grouped with other global declarations and at the beginning
of the program file.
• A local variable (declaration) is inside the body of a function.
– Locally declared variables cannot be accessed outside of the function
they were declared in.
– Possible to declare the same identifier name in different parts of the
program.
4
Example
int y = 38; // global variable
double x;
void f(int, int);
void main( )
{
int z=47; // local variable
while(z<400) {
int a = 90;
z += a++;
z++;
}
y = 2 * z;
f(1, 2);
}
void f(int s, int t)
{
int r = 12;
int z = 27;
s = r + t + y;
s += z;
}
5
Global Variables
• Undisciplined use of global variables may lead to confusion
and debugging difficulties.
– Example?
• Instead of using global variables in functions, try passing local
variables by reference.
File I/O
• Before a file can be read or written, it has to be opened by
the library function fopen. fopen takes an external name like
data.txt, does some housekeeping and negotiation with the
operating system, and returns a pointer to be used in
subsequent reads or writes of the file.
• This pointer points to a structure FILE.
FILE *fp;
fopen
FILE *fopen(char *name, char *mode);
void fclose(FILE* stream)
• fopen returns a pointer to a FILE.
• FILE is a type name. It is defined with a typedef.
• mode can be
–
–
–
–
r - read
w - write
a - append
a “b” can be appended to the mode string to work with binary files.
For example, “rb” means reading binary file.
Text Files - fprintf and fscanf
• int fprintf(FILE *fp, char *format, ...);
• int fscanf(FILE *fp, char *format, ...);
• int feof(FILE *fp); // return 1/0 end-of-file is reached
• Similar to printf and scanf.
Example – create and write to a file
#include <stdio.h>
int main()
{
FILE *fp;
char name[10];
double balance;
int account;
if ((fp = fopen(“clients.dat”, “w”)) == null) {
printf(“File could not be opened\n”);
}
else {
printf(“Enter one account, name, and balance.\n”);
scanf(“%d%s%lf”, &account, name, &balance);
fprintf(fp, "%d %s %.2f\n", account, name, balance);
fclose(fp);
}
return 0;
}
Example – read from a file
#include <stdio.h>
int main()
{
FILE *fp;
char name[10];
double balance;
int account;
if ((fp = fopen(“clients.dat”, “r”)) == null) {
printf(“File could not be opened\n”);
}
else {
fscanf(fp, “%d%s%lf”, &account, name, &balance);
printf("%d %s %.2f\n", account, name, balance);
fclose(fp);
}
return 0;
}
Binary Files - fread and fwrite
size_t fread(void *array, size_t size, size_t count, FILE *fp);
size_t fwrite(void *array, size_t size, size_t count, FILE *fp);
• array must be a pointer
• size - size of elements in this array
• count - number of elements in this array
Example
#include <stdio.h>
int main()
{
FILE *fp;
float value[3];
fp = fopen(“account.txt”, "rb");
fread(value, sizeof(float), 3, fp);
printf("%f\t%f\t%f\n", value[0], value[1], value[2]);
fclose(fp);
return 0;
}
Example
#include <stdio.h>
int main()
{
FILE *fp;
float value[3] = {1.0, 2.0, 3.0};
fp = fopen(“account.txt”, “wb");
fwrite(value, sizeof(float), 3, fp);
fclose(fp);
return 0;
}
Example
#include <stdio.h>
int main()
{
FILE *fp;
float value[300] = {1.0, 2.0, 3.0};
fp = fopen(“account.txt”, “wb");
fprintf(fp, “%lf %lf %lf\n”, value[0], value[1], value[2], …);
// fwrite(value, sizeof(float), 300, fp);
fclose(fp);
return 0;
}
getchar() & putchar()
#include <stdio.h>
#include <ctype.h>
int main()
{
int c;
while ((c = getchar()) != EOF)
{
putchar(tolower(c));
}
return 0;
}
<ctype.h> includes many useful functions.
The argument for these functions is a single char.
Table 7.1. ctype.h character-testing functions.
Name
True If Argument Is
isalnum()
Alphanumeric (alphabetic or numeric)
isalpha()
Alphabetic
iscntrl()
A control character, such as Ctrl+B
isdigit()
A digit
isgraph()
Any printing character other than a space
islower()
A lowercase character
isprint()
A printing character
ispunct()
A punctuation character (any printing character other than a space or an alphanumeric character)
isspace()
isupper()
A whitespace character: space, newline, formfeed, carriage return, vertical tab, horizontal tab, or, possibly, other
implementation-defined characters
An uppercase character
isxdigit()
A hexadecimal-digit character
Table 7.2. ctype.h character-mapping functions.
Name
Action
tolower()
If the argument is an uppercase character, returns the lowercase version; otherwise, just returns the original argument
toupper()
If the argument is a lowercase character, returns the uppercase version; otherwise, just returns the original argument
Variable-length Argument Lists
• Let's implement a minimal version of printf.
• Use “...” to indicate that the number and types of these
arguments may vary.
• The declaration “...” can only appear at the end of an
argument list.
void minprintf(char *format, ...)
What Do We Need?
• type va_list - declare a variable that will refer to each
argument in turn, assume ap
• macro va_start - initialize ap to point to the rst unnamed
argument
• function va_arg - Each call of va_arg returns one argument
and steps ap to the next; va_arg uses a type name to
determine what type to return and how big a step to take.
• function va_end - do whatever cleanup is necessary. It must
be called before the program returns.
#include <stdarg.h>
void minprintf(char *format, ...) {
va_list ap; // points to each unnamed arg in turn
char *p, *sval;
int ival;
va_start(ap, format); // make ap point to 1st unnamed arg
for (p = format; *p; ++p) {
if (*p != '%') {
putchar(*p);
continue;
}
switch (*++p) {
case 'd':
ival = va_arg(ap, int);
printf("%d", ival);
break;
case 's':
for (sval = va_arg(ap, char *); *sval; ++sval) {
putchar(*sval);
}
break;
default:
putchar(*p);
}
}
va_end(ap); // clean up when done
}
What Do We Need?
• type va_list - declare a variable that will refer to each
argument in turn, assume ap
• macro va_start - initialize ap to point to the rst unnamed
argument
• function va_arg - Each call of va_arg returns one argument
and steps ap to the next; va_arg uses a type name to
determine what type to return and how big a step to take.
• function va_end - do whatever cleanup is necessary. It must
be called before the program returns.
Download