In this Lab, you will practise:
Create a new directory for this lab called lab09
by typing:
mkdir lab09Change to this directory by typing:
cd lab09
one.c
, which reads in a string from standard input and writes out the characters
one per line.
The output from your program should look like this:
./one Enter a string: Hello H e l l o
Hint: don't use scanf, use fgets to read the string.
Note, your program needs to read only one string - it doesn't have to read until the end of input.
You can assume lines contain at most 4096 characters.
As usual autotest is available to test your program.
~cs1511/bin/autotest lab09 one.c
one.c
// Read a string and then print the letters one per line // written by Andrew Taylor andrewt@cse.unsw.edu.au // April 2017 as a COMP1511 lab exercise // #include <stdio.h> #define MAXLINE 4094 int main(void) { char line[MAXLINE]; int i; printf("Enter a string: "); fgets(line, MAXLINE, stdin); i = 0; while (line[i] != '\n' && line[i] != '\0') { printf("%c\n", line[i]); i = i + 1; } return 0; }
Write a program, palindrome.c
, which reads a string and tests if
it is a palindrome.
For example:
./palindrome Enter a string: kayak String is a palindrome ./palindrome Enter a string: canoe String is not a palindromeHint: don't use scanf, use fgets to read the string.
Note, your program needs to read only one string - it doesn't have to read until the end of input.
You can assume lines contain at most 4096 characters.
As usual autotest is available to test your program.
~cs1511/bin/autotest lab09 palindrome.c
palindrome.c
// // Read a string and then indicate if it is a palindrome // written by Andrew Taylor andrewt@cse.unsw.edu.au // April 2017 as a COMP1511 lab exercise // #include <stdio.h> #define MAXLINE 4094 int main(int argc, char *args[]) { char line[MAXLINE]; int left, right; printf("Enter a string: "); fgets(line, MAXLINE, stdin); left = 0; right = 0; while (line[right] != '\0' && line[right] != '\n') { right = right + 1; } if (right == 0) { return 0; } right = right - 1; while (left < right) { if (line[left] != line[right]) { printf("String is not a palindrome\n"); return 0; } left = left + 1; right = right - 1; } printf("String is a palindrome\n"); return 0; }
numbers.c
which takes 3 arguments which
creates a file containing specified integers, one per line. The first & second arguments
will specify a range of integers. The third argument will specify the file
to be created. For example:
./numbers 40 42 fortytwo.txt cat fortytwo.txt 40 41 42 ./numbers 1 5 a.txt cat a.txt 1 2 3 4 5 ./numbers 1 1000 1000.txt wc 1000.txt 1000 1000 3893 1000.txtYou should print a suitable error message if given the wrong number of arguments or if the file can not be created. As usual autotest is available to test your program.
~cs1511/bin/autotest lab09 numbers.c
numbers.c
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { if (argc != 4) { fprintf(stderr, "Usage: %s: <start> <finish> <file>\n", argv[0]); exit(1); } int start = atoi(argv[1]); int finish = atoi(argv[2]); FILE *stream = fopen(argv[3], "w"); if (stream == NULL) { perror(argv[3]); exit(1); } for (int i = start; i <= finish; i = i + 1) { fprintf(stream, "%d\n", i); } fclose(stream); return 0; }
head.c
, which given a filename as argument prints the first 10 lines
of the file. If the file has less than 10 lines the entire file should be printed.
Note unlike the 2 previous exercises this program should not create any files. Its just prints part of the content of a file to standard output.
For example:
./head 1000.txt 1 2 3 4 5 6 7 8 9 10 ./head /usr/include/stdio.h /* Define ISO C stdio on top of C++ iostreams. Copyright (C) 1991-2016 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful,It should also be possible to specify that a different number of lines be printed. This will specified by passing the string "-n" as the first argument to the program, the number of lines to be printed as the second argument and the file as the third argument. For example:
./head -n 3 1000.txt 1 2 3You should print a suitable message if incorrect arguments are supplied or the file can not be read.
You can assume lines have at most 1024 characters, but if possible avoid this assumption.
As usual autotest is available to test your program.
~cs1511/bin/autotest lab09 head.c
head.c
#include <stdio.h> #include <string.h> #include <stdlib.h> #define DEFAULT_NLINES 10 void head(char *filename, int nLines) { FILE *f; int ch, lines; f = fopen(filename, "r"); if (f == NULL) { perror(filename); exit(1); } lines = 0; while (lines < nLines) { ch = fgetc(f); if (ch == EOF) { fclose(f); return; } putchar(ch); if (ch == '\n') { lines = lines + 1; } } fclose(f); } #define MAX_LINE_LENGTH 1024 // Alternative version using fgets // - has the disadvantage of a maximum line length. void head1(char *filename, int nLines) { int lineNumber; char line[MAX_LINE_LENGTH + 2]; FILE *f = fopen(filename, "r"); if (f == NULL) { perror(filename); exit(1); } lineNumber = 0; while (lineNumber < nLines && fgets(line, MAX_LINE_LENGTH, f) != NULL) { lineNumber = lineNumber + 1; fputs(line, stdout); } fclose(f); } int main(int argc, char *argv[]) { int nLines; char *filename; if (argc == 2) { nLines = DEFAULT_NLINES; filename = argv[1]; } else if (argc == 4 && strcmp(argv[1], "-n") == 0) { nLines = atoi(argv[2]); filename = argv[3]; } else { fprintf(stderr, "Usage: head [-n lines] <file>"); exit(1); } head(filename, nLines); return 0; }
palindrome1.c
) so characters which are not letters
are ignored and difference between upper case and
lower case are ignored.
For example:
./palindrome1 Enter a string: Do geese see God? String is a palindrome ./palindrome1 Enter a string: Do ducks see God? String is not a palindrome ./palindrome1 Enter a string: Madam, I'm Adam String is a palindrome ./palindrome1 Enter a string: Madam, I'm Andrew String is not a palindrome
Hint: if you #include <ctype.h>
you can use a C library function named tolower
to convert a character to lower case.
~cs1511/bin/autotest lab09 palindrome1.c
palindrome1.c
// // Read a string and then indicate if it is a palindrome // only lower case alphabetic letters are considered // written by Andrew Taylor andrewt@cse.unsw.edu.au // April 2017 as a COMP1511 lab exercise // #include <stdio.h> #include <ctype.h> #define MAXLINE 4094 int main(int argc, char *args[]) { char line[MAXLINE]; int left, right ; printf("Enter a string: "); fgets(line, MAXLINE, stdin); left = 0; right = 0; while (line[right] != '\0' && line[right] != '\n') { line[right] = tolower(line[right]); right = right + 1; } if (right == 0) { return 0; } right = right - 1; while (left < right) { // printf("line[%d]='%c'line[%d]='%c'\n", left, line[left], right, line[right]); if (line[left] < 'a' || line[left] > 'z') { left = left + 1; } else if (line[right] < 'a' || line[right] > 'z') { right = right - 1; } else if (line[left] != line[right]) { printf("String is not a palindrome\n"); return 0; } else { left = left + 1; right = right - 1; } } printf("String is a palindrome\n"); return 0; }
tail.c
, which given a filename as argument prints the last 10 lines
of the file. If the file has less than 10 lines the entire file should be printed.
You can assume lines have at most 1024 characters, but you can not make any assumption about how many lines are in the file.
You can not read the entire file into an array.
For example:
./tail 1000.txt 991 992 993 994 995 996 997 998 999 1000 ./numbers 1 100000 100000.txt wc 100000.txt 100000 100000 588895 100000.txt ./tail 100000.txt 99991 99992 99993 99994 99995 99996 99997 99998 99999 100000
You should print a suitable message if incorrect arguments are supplied or the file can not be read.
Unlike the previous exercise it does not have to be possible to specify a different number of lines to be printed.
As usual autotest is available to test your program.
~cs1511/bin/autotest lab09 tail.c
tail.c
#include <stdio.h> #include <string.h> #include <stdlib.h> #define NLINES 10 #define MAX_LINE_LENGTH 1024 // https://en.wikipedia.org/wiki/Circular_buffer explains // how the array line is used here int main(int argc, char *argv[]) { char line[NLINES][MAX_LINE_LENGTH]; // line buffer int lineNumber, i; FILE *stream; if (argc != 2) { fprintf(stderr, "Usage: tail [-n lines] <file>"); exit(1); } stream = fopen(argv[1], "r"); if (stream == NULL) { fprintf(stderr, "%s: %s: ", argv[0], argv[1]); perror(""); exit(1); } lineNumber = 0; while (fgets(line[lineNumber % NLINES], MAX_LINE_LENGTH, stream) != NULL) { lineNumber = lineNumber + 1; } fclose(stream); i = lineNumber - NLINES; if (i < 0) { i = 0; } while (i < lineNumber) { printf("%s", line[i % NLINES]); i = i + 1; } return 0; }
lab09
directory):
give cs1511 lab09 one.c palindrome.c numbers.c head.c palindrome1.c tail.cSubmit the challenge exercises only if you attempt them.
If you are working at home, you may find it more convenient to upload your work via give's web interface.
Remember the lab assessment guidelines - if you don't finish the exercises
you can finish them in your own time, submit them
by Monday 11:00am using give
and ask your tutor to assess them at the start of
the following lab.
Either or both members of a programming pair can submit the work (make sure each program lists both of you as authors in the header comment).