220 likes | 237 Views
Learn how to manipulate files and utilize command line arguments in C programming with functions for input/output operations. Explore File Handling in C.
E N D
Introduction to Computer Organization & Systems COMP 21000 Topics: • C I/O John Barr
Output: printf printf(“score = %d\n”,score);
Input: scanf scanf(“%d %d”,&exam1, &exam2);
Variable fname is a file pointer File I/O #include <stdio.h> #include <stdlib.h> #define SIZE 10 int main() { int line[SIZE]; int n; FILE *fname; /* verify that we can open the file */ if ( (fname = fopen("nums.txt", "r")) == NULL) { fprintf(stderr, "cannot open nums.txt for reading"); exit(1); } for (n = 0; n < 10; n++) { fscanf(fname, "%d", &line[n]); printf("Entered %d\n", line[n]); } for (n = 0; n < 10; n++) { printf("n = %d \t line = %d\n", n, line[n]); } printf ("Goodbye! \n"); return 0; } Function fopen will open the file given as the first argument of the command line. Function fscanf reads from the file indicated by its first argument. See /home/barr/Student/comp210/examples/readNum.c fopen reference: https://www.tutorialspoint.com/c_standard_library/c_function_fopen.htm
Variable fname is a file pointer File I/O #include <stdio.h> #include <stdlib.h> #define SIZE 10 int main() { int line[SIZE]; int n; FILE *fname; /* verify that we can open the file */ if ( (fname = fopen("nums2.txt", "w")) == NULL) { fprintf(stderr, "cannot open nums.txt for writing"); exit(1); } printf("Enter 10 numbers: "); // continued on next slide Function fopen will open the file given as the first argument of the command line. See /home/barr/Student/comp210/examples/writeNum.c Continued on next slide
File I/O Scanning from stdin for (n = 0; n < 10; n++) { scanf("%d", &line[n]); printf("Entered %d\n", line[n]); } for (n = 0; n < 10; n++) { fprintf(fname, "n = %d \t line = %d\n", n, line[n]); } printf ("Goodbye! \n"); return 0; } Function fprintf writes to the file indicated by its first argument.
Argc indicates the number of command line arguments (including the program name). Argv is an array of pointers to char (strings) that lists all of the command line arguments. Command Line intmain(int argc, char *argv[ ]) { int j; if (argc != 2) { printf("factorial takes one integer argument\n"); return(1); /* abnormal termination. */ } /* ASCII string to integer conversion */ j = atoi(argv[1]); printf("factorial(%d) = %d\n", j, factorial(j)); return(0); }
Command Line #include <stdio.h> intfactorial (int n) { int ans = 1; while (n > 1) { ans *= n; n = n - 1; } return(ans); }
Variable fname is a file pointer File I/O #include <stdio.h> #include <stdib.h> #define SIZE 100 intmain(intargc, char *argv[ ]) { char line[SIZE]; int n; FILE *fname; if (argc <2) { fprintf(stderr, "%s : you must include a file name \n",argv[0]); exit(1); } /* verify that we can open the file */ if ( (fname = fopen(argv[1], “w”)) == NULL) { fprintf(stderr, “%s: cannot open %s for writing”, argv[0], argv[1]); exit(1); } printf(“Enter some lines. End your input with ^d: \n”); while ( (n = readline(line, SIZE) ) > 0) fprintf(fname, “n = %d \t line = %s\n”, n, line); printf (“Goodbye! \n”); }:w 3G Function fopen will open the file given as the first argument of the command line. Function fprintf writes to the file indicated by its first argument. See /home/barr/Student/comp210/examples/readNumCmd.c
File I/O /* This function will read an entire line including white space until either a newline character of the EOF character is found */ intreadline(char s[ ],int max) { intc,i=0; max--; while (i < max && (c = getchar()) != EOF && c != '\n') s[i++] =c; if (c == '\n') s[i++] = c; s[i] = '\0'; return(i); }
File I/O: reading part 1 #include <stdlib.h> #include <stdio.h> int main(intargc, char *argv[]) { int *line[5]; int n, i, *ptr; FILE *fname; if (argc <2) { // if there is no command line argument, use a default name fname = fopen("ints.txt", "r"); } else fname = fopen(argv[1], "r"); // error check; did the file open? if (fname == NULL) { fprintf(stderr, "Could not open %s\n", argv[1]); exit(1); } Reading files using dynamic memory fnameis the file descriptor variable here’s where we open the file See ex3.7.c
File I/O: reading part 2 for (n = 0; n < 5; n++) line[n] = (int *)malloc(4*sizeof(int)); for (n = 0; n < 5; n++) { ptr = line[n]; for (i = 0; i < 4; i++) { fscanf(fname, "%d", ptr++); } } printf( "The numbers are: \n"); for (n = 0; n < 5; n++){ for (i = 0; i < 4; i++) { printf("%d ", line[n][i]); } printf("\n"); } } Dynamically allocate memory here’s where we read in from the file
Other IO functions #include<stdio.h> intfgetc(FILE*stream); char*fgets(char*s,intsize,FILE*stream); intgetc(FILE*stream); intgetchar(void); char*gets(char*s); intungetc(intc,FILE*stream);
Other IO functions int fgetc( std::FILE* stream ); reads the next character from stream and returns it as an unsignedchar cast to an int, or EOF on end of file or error. int getc( std::FILE* stream );is equivalent to fgetc() except that it may be implemented as a macro which evaluates stream more than once. getchar() is equivalent to getc(stdin).
Other IO functions char* gets( char* str ); reads a line from stdin into the buffer pointed to by str until either a terminating newline or EOF, which it replaces with '\0'. No check for buffer overrun is performed. char* fgets( char* str, int n, FILE* stream ); reads in at most one less than n characters from stream and stores them into the buffer pointed to by str. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A '\0' is stored after the last character in the buffer. ungetc() pushes c back to stream, cast to unsignedchar, where it is available for subsequent read operations. Pushed - back characters will be returned in reverse order; only one pushback is guaranteed.
Scanf problems • How is white space handled? • scanf(“%d”, &x); • User enters 25\n • The ‘\n’ may stay in the input stream • Solutions: • scanf(“%d “, &x); Note the space after the ‘d’
Scanf problems • How is white space handled? • scanf(“%d”, &name); • User enters John Barr • The variable name now holds “John” • Solutions: printf("Enter a string\n"); scanf("%[^\n]s", str1); __fpurge(stdin); char name[32] Note the space after the ‘John’ Reads all char except ‘\n’ char But will read the final ‘\n’ so must purge
Scanf problems • A better way to read a string fgets( char* str, int n, stdin ); • User enters John Barr fgets(str1, MAX, stdin); if ((strlen(str1) > 0) && (str1[strlen (str1) - 1] == '\n')) str1[strlen (str1) - 1] = '\0'; Reads up to MAX char or to the ‘\n’ char Also reads the ‘\n’ char We put a ‘\0’ in place of the ‘\n’ if necessary
Scanf problems Reads all char up to the ‘\n’ char i.e., says continue reading but don’t read the ‘\n’ • Solutions: • scanf(”%[^\n]", &name); • Brackets [] • List the characters to match. Will only scan in matched characters. • If begin with a ^ then these are characters to ignore. • If use a hyphen, matches all in between characters, e.g., [a-g] • Input stops as soon as the first non-acceptable character is read • Note that with brackets you don’t need a formatting character. Brackets are always read as a string.
Example 1 #include <stdio.h> 2 3 intmain(){ 4 charname[32]; 6 printf("Enter a namewithspaces: "); 7 scanf("%[^\n]", name); 8 printf("\nname: %s\n", name); 9 // zero out the name 10 name[o] = ‘\0’; 12 printf("Enter somecharacters: "); 13 scanf("%*[\n]%[a-g]", name); // ignoresthenewlinechar 14 printf("acceptedcharacters: %s\n", name); 15 scanf("%s", name); 16 printf("unaccepted characters: %s\n", name); 17 // zero out the name 18 name[o] = ‘\0’; 19 printf("Now enter 3 characters: "); 20 scanf(“%3s”, name); • printf("The 3 characters are: %s\n", name); 23 } testRead Enter a name with spaces: John Barr name: John Barr Enter some characters: abchijdef accepted characters: abc unaccepted characters: hijdef Now enter 3 characters: mnopq The 3 characters are: mno See Student/Comp210/examples/testRead.c
Scanf problems • scanf formatting string:% * maximum-field-width length Letter
Scanf problems • Buffer overflow? • scanf(“%d”, &name); • User enters John Barr • Major source of exploits • Solutions: • scanf(”%4[^\n]", &name); char name[4] Overflows the allocated memory Only reads 4characters