#include <stdio.h> int main(void) { char str[10]; str[0] = 'H'; str[1] = 'i'; printf("%s", str); return 0; }
printf
, like many C library functions expects strings to be null-terminated.
In other words printf
, expects the array str
to contain an element with value '\0'
which marks the end of the sequence of characters to be printed.
printf
will print str[0]
('H'), str[1]
then examine
str[2]
.
Code produced by dcc --valgrind
will then stop with an error because
str[2]
is uninitialized.
The code with gcc will keep executing and printing element from str
until
it encounters one containing '\0'. Often str[2]
will by chance contain '\0'
and the program will work correctly.
Another common behaviour will be that the program prints some extra "random" characters.
It is also possible the program will index outside the array which would result in it stopping
with an error if it was compiled with dcc
.
If the program was compiled with gcc and uses indexes well outside the array it may be terminated by the the operating system because of an illegal memory access.
#include <stdio.h> int main(void) { char str[10]; str[0] = 'H'; str[1] = 'i'; str[2] = '\0'; printf("%s", str); return 0; }
#include <stdio.h> #define MAX_LINE 4096 int main(void) { char line[MAX_LINE]; int i; while (fgets(line, MAX_LINE, stdin) != NULL) { i = MAX_LINE; while (line[i] != '\n') { i = i - 1; } printf("line %d characters long\n", i); } return 0; }
line[MAX_LINE]
which is an illegal array index
line[-1]
).
line_length.c
which reads lines from its input and prints
how many characters each line contains.
The only functions you can use are fgets
and printf
.
You can assume lines contain at most 4096 characters.
For example:
./line_length Andrew Rocks line 12 characters long A very long line. line 17 characters long short line 5 characters long line 0 characters long
line_length.c
#include <stdio.h> #define MAX_LINE 4096 int main(void) { char line[MAX_LINE]; int i; while (fgets(line, MAX_LINE, stdin) != NULL) { i = 0; while (line[i] != '\n' && line[i] != '\0') { i = i + 1; } printf("line %d characters long\n", i); } return 0; }Heavily commented sample solutions for
line_length.c
// COMP1511 W9 tutorial question 5 #include <stdio.h> #include <stdlib.h> #define MAX 4096 // prototype, returns an integers and takes in a string called line int count (char* line); int main (void) { char line[MAX]; // holder for each line while (fgets(line, MAX, stdin) != NULL) { // so read in successfully printf("line %d characters long\n", count(line)); } return EXIT_SUCCESS; } int count (char* line) { int i = 0; while (line[i] != '\0') { i++; } // exited when index i is the null terminating character // so size is one less i -= 1; return i; }
If fopen is successful it returns a pointer to the file stream that has been opened, otherwise it returns NULL
#include <stdio.h> #define MAX_LINE 1024 int main(void) { char line[MAX_LINE]; FILE *stream; stream = fopen("data.txt", "r"); if (stream == NULL) { fprintf(stderr,"data.txt can't be opened for reading\n"); return 1; } if (fgets(line, MAX_LINE, stream) != NULL) { printf("%s", line); } fclose(stream); // unneeded return 0; }Heavily commented sample solutions.
// COMP1511 W9 Tut Question 8 #include <stdio.h> #include <stdlib.h> #define MAX_LINE 4096 int main (void) { char line[MAX_LINE]; // holder for the line string FILE *f; // file pointer f = fopen("data.txt", "r"); if (f == NULL) { // couldn't open the file, print an error message // to standard error fprintf(stderr, "data.txt can't be opened for reading\n"); return EXIT_FAILURE; } // else you could read the file, display first line on scream if (fgets(line, MAX_LINE, f) != NULL) { printf("%s", line); } fclose(f); // good practice return EXIT_SUCCESS; }
#include <stdio.h> #define MAX_LINE 1024 int main(void) { char line[MAX_LINE]; FILE *stream; stream = fopen("data.txt", "w"); if (stream == NULL) { fprintf(stderr,"data.txt can't be opened for writing\n"); return 1; } fgets(line, MAX_LINE, stdin); fprintf(stream, "%s", line); fclose(stream); // necessary when writing to a file return 0; }Heavily commented sample solutions.
// COMP1511 W9 Tutorial Question 9 #include <stdlib.h> #include <stdio.h> #define MAX 4096 int main (void) { char line[MAX]; FILE *f; f = fopen("data.txt", "w"); if (f == NULL) { // error opening file fprintf(stderr, "data.txt can't be opened for writing\n"); return EXIT_FAILURE; } // else read successfully, write text to file fgets(line, MAX, stdin); // get line from stdin fprintf(f, "%s", line); // write to file fclose(f); return EXIT_SUCCESS; }
#include <stdio.h> #define MAX_LINE 1024 int main(void) { char line[MAX_LINE]; FILE *stream; stream = fopen("data.txt", "a"); if (stream == NULL) { fprintf(stderr,"data.txt can't be opened for writing\n"); return 1; } fgets(line, MAX_LINE, stdin); fprintf(stream, "%s", line); fclose(stream); // necessary when writing to a file return 0; }Heavily commented sample solutions.
// COMP1511 W9 Tutorial Question 10 #include <stdio.h> #include <stdlib.h> #define MAX 1024 int main (void) { char line[MAX]; // open file for appending FILE *fp = fopen("data.txt", "a"); if (fp == NULL) { fprintf(stderr, "data.txt can't be opened for writing.\n"); return EXIT_FAILURE; } // get line of input from user printf("Enter a line of text:\n"); fgets(line, MAX, stdin); // write it to the file fprintf(fp, "%s", line); // close the file fclose(fp); // necessary when writing to a file return EXIT_SUCCESS; }
Your tutor may still choose to cover some of the questions time permitting.
file_max.c
that reads a set of integer numbers from a file and prints out
the maximum number to standard output. The name of the input file should be
specified as a command line argument.
file_max.c
#include <stdio.h> int main(int argc, char *argv[]) { FILE *fp; int num; int max; int numbersRead; if (argc < 2) { fprintf(stderr, "Usage: %s <filename>\n", argv[0]); return 1; } fp = fopen(argv[1], "r"); if (fp == NULL) { fprintf(stderr, "%s: unable to open file %s,\n", argv[0], argv[1]); return 1; } numbersRead = 0; while (fscanf(fp, "%d", &num) == 1) { if (numbersRead == 0 || num > max) { max = num; } numbersRead = numbersRead + 1; } if (numbersRead > 0) { printf("Max : %d\n",max); } fclose(fp); return 0; }Heavily commented sample solutions.
// COMP1511 W9 Tutorial Question 11 #include <stdlib.h> #include <stdio.h> int main (int argc, char* argv[]) { char *name; // file name FILE *f; // file pointer int num, max; // number we're reading in, keep track of max number we've seen int numRead = 0; // counter for number of integers we've read in from file // check that user specified file name as command line argument if (argc < 2) { // less than 2 command line arguments, so didn't specify filename // print out helpful message fprintf(stderr, "Usage: %s <filename>\n", argv[0]); return EXIT_FAILURE; } // file name in argv[1] name = argv[1]; // redundant, this is just for readability // open file for reading f = fopen(name, "r"); if (f == NULL) { // file opening error fprintf(stderr, "%s: unable to open file %s\n", argv[0], name); return EXIT_SUCCESS; } // everything is working fine now! // read the numbers from the file while (fscanf(f, "%d", &num) == 1) { // is this the max number? if (numRead == 0 || num > max) { // either this is the first number // or this number is greater than our max max = num; } numRead++; } // print out max if you read in some numbers (so max initialized) if (numRead > 0) { printf("Max: %d\n", max); } // close file pointer, good practice fclose(f); return EXIT_SUCCESS; }
strip_comments.c
which reads lines from its input and prints
them after removing any C // style comments. In another words if the line contains //
it does not print the // or anything after it.
The only functions you can use are fgets
and printf
.
You can assume lines contain at most 4096 characters.
For example:
./strip_comments x = x + 1; // This means add one to the variable x x = x + 1;Also - is that a good comment to add to a C program?
strip_comments.c
#include <stdio.h> #define MAX_LINE 4096 int main(void) { char line[MAX_LINE]; int i; while (fgets(line, MAX_LINE, stdin) != NULL) { // strip // style comments from input i = 0; while (line[i] != '\n' && line[i] != '\0') { // safe to look at line[i+1] because // we know here line[i] != '\0' if (line[i] == '/' && line[i + 1] == '/') { // replace // with end of -line line[i] = '\n'; line[i + 1] = '\0'; // could break here but loop will stop anyway } i = i + 1; } // write possibly-modified line printf("%s", line); } return 0; }Heavily commented sample solutions.
// COMP1511 W9 Tut Question 12 #include <stdio.h> #include <stdlib.h> #define MAX 4096 int main (void) { char line[MAX]; // holder for each line int i; // counter for line while (fgets(line, MAX, stdin) != NULL) { // strip the // comments from input // iterate through line and see if we encounter a '/' then '/' // everything after is a comment, so stop the string there i = 0; while (line[i] != '\n' && line[i] != '\0') { if (line[i] == '/' && line[i + 1] == '/') { // found a comment, blank out this comment line[i] = '\0'; break; } i++; } // print out edited(?) line to output printf("%s\n", line); // can print out '\n' or not // depending on where the comment is (or if there's no comment) // might have an extra blank line printed } return EXIT_SUCCESS; }
filter_empty_lines.c
which reads lines from its input and prints
them only if they contain a non-white-space-character.
In another words remove lines are empty or contain only white-space.
The only functions you can use are fgets
and printf
.
You can assume lines contain at most 4096 characters.
You can assume there are only 3 white space characters, space, tab & new-line.
For example:
./filter_empty_lines full line full line another no-empty line another no-empty line
filter_empty_lines.c
#include <stdio.h> #define MAX_LINE 4096 int main(void) { char line[MAX_LINE]; int i; int whiteSpaceCount; while (fgets(line, MAX_LINE, stdin) != NULL) { // print lines iff they contain a non white-space character i = 0; whiteSpaceCount = 0; while (line[i] != '\0') { // test for white space (isspace would be better here) if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n') { whiteSpaceCount = whiteSpaceCount + 1; // could break here } i = i + 1; } if (whiteSpaceCount > 0) { printf("%s", line); } } return 0; }Heavily commented sample solutions.
// COMP1511 W9 Tut Question 13 #include <stdio.h> #include <stdlib.h> #define MAX 4096 #define TRUE 1 #define FALSE 0 int main(void) { char line[MAX]; int i; // counter for iterating through line int nonWhitespace; // "boolean" value for if you've seen a whitespace char or not in this line while (fgets(line, MAX, stdin) != NULL) { // assume no whitespace nonWhitespace = FALSE; i = 0; while (line[i] != '\n' && line[i] != '\0') { if ((line[i] != ' ') && (line[i] != '\t') && (line[i] != '\n')) { // this is a non-whitespace character nonWhitespace = TRUE; break; } i++; } // print the line if it has whitespace if (nonWhitespace == TRUE) { printf("%s", line); } } return EXIT_SUCCESS; }
reverse.c
which reads lines and writes them out
with the characters of each line in reverse order.
It should stop when it reaches the end of input.
For example:
./reverse The quick brown fox jumped over the lazy dog. .god yzal eht revo depmuj xof nworb kciuq ehT It was the best of times. It was the worst of times. .semit fo tsrow eht saw tI .semit fo tseb eht saw tI This is the last line. .enil tsal eht si sihT <control-d>
reverse.c
#include <stdio.h> #define MAX_LINE 4096 int main(void) { char line[MAX_LINE]; int i; while (fgets(line, MAX_LINE, stdin) != NULL) { i = 0; while (line[i] != '\n' && line[i] != '\0') { i = i + 1; } i = i - 1; while (i >= 0) { printf("%c", line[i]); i = i - 1; } printf("\n"); } return 0; }Heavily commented sample solutions.
// COMP1511 W9 Tutorial Problem 14 #include <stdio.h> #include <stdlib.h> #define MAX 4096 int main(void) { char line[MAX]; int i; // counter for line int size; // size of this line // get the lines while (fgets(line, MAX, stdin) != NULL) { // find the size of this line i = 0; while ((line[i] != '\n') && (line[i] != '\0')) { // not the end yet i++; } // when we exit, i is the index of newline or null terminating size = i - 1; // largest index of non-ending char // now print in reverse i = size; // could get rid of size and jsut write i = i-1 while (i >= 0) { printf("%c", line[i]); i--; } // separate this line printf("\n"); } return EXIT_SUCCESS; }