#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;
}