#include <stdio.h> // for getchar(), putchar(), printf(), EOF
#define MAXLINE 1000 // maximum input line size
int getLine(char line[], int maxline); // getline() is declared in stdio.h
// int getLine(char [], int); // alternative declaration
void copy(char to[], char from[]);
// void copy(char [], char []); // alternative declaration
int main()
{
int len; // current line length
int max; // maximum length seen so far
char line[MAXLINE]; // current input line
char longest[MAXLINE]; // longest line saved here
max = 0; // initialize
while((len = getLine(line, MAXLINE)) > 0)
{ // line containing only '\n' not empty
if (len > max)
{
max = len;
copy(longest, line);
}
}
if (max > 0) // there was a line
{
printf("%s", longest);
if (longest[max-1] != '\n')
{putchar('\n');} // line may not end with '\n'
}
return 0;
}
// getLine(): read a line into s[], return length
int getLine(char s[], int lim) // returns 0 at EOF
{
int c = EOF; // initialize
int i;
// getchar() is only executed if (i < (lim-1)):
for (i = 0; i < (lim-1) && (c = getchar()) != EOF && c != '\n'; i++)
{ // from 0 to lim-2; s[lim-2]='\n' or not, s[lim-1]='\0'
s[i] = c;
}
if (c == '\n') // i < (lim-1), getchar() executed
{
s[i] = c; // '\n'
i++;
}
s[i] = '\0'; // the null character ends a string
return i; // max(i) == (lim-1), assuming (lim-1) > 0
}
// copy(); copy from[] into to[]; assume to[] is big enough
void copy(char to[], char from[])
{
int i;
for (i = 0; (to[i] = from[i]) != '\0'; i++)
{} // ends after copying '\0'
}
/*
gcc longest.c -o longest
./longest // input from the keyboard
The sky is gray
A storm is coming
Rain fills the rivers // Enter, then EOF (Ctrl+D in Linux, Ctrl+Z+Enter in Windows)
Rain fills the rivers
./longest < longest.c // source file
Rain fills the rivers // Enter, then EOF (Ctrl+D in Linux, Ctrl+Z+Enter in Windows)
./longest < longest // binary file
ELF // line contains '\0', which ends copy() and printf ("%s")
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
Exercise 1-16. Revise the main routine of the longest-line program so it will correctly print the length of arbitrarily long input lines, and as much as possible of the text.
#include <stdio.h> // for getchar(), printf(), EOF
#define MAXLINE 1000 // maximum input line size printed
long getLine(char line[], int maxline); // getline() is declared in stdio.h
// long getLine(char [], int); // alternative declaration
void copy(char to[], char from[]);
// void copy(char [], char []); // alternative declaration
// getLine() returns the size of an arbitrarily long line
// program prints longest line up to MAXLINE characters
int main()
{
long len; // current line length
long max; // maximum length seen so far
char line[MAXLINE]; // current input line
char longest[MAXLINE]; // longest line saved here
max = 0; // initialize
while((len = getLine(line, MAXLINE)) > 0)
{ // line containing only '\n' has length 1
if (len > max)
{
max = len;
copy(longest, line);
}
}
if (max > 0) // there was a line
{
printf("Length: %ld\n", max);
printf("%s\n", longest); // line may not end with '\n'
}
return 0;
}
// getLine(): read a line into s[] up to MAXLINE-1 chars, return total length
long getLine(char s[], int lim) // returns 0 at EOF
{
int c = EOF; // initialize
long i; // length of an arbitrarily long line
// getchar() is only executed if (i < (lim-1)):
for (i = 0; i < (lim-1) && (c = getchar()) != EOF && c != '\n'; i++)
{ // from 0 to lim-2; s[lim-2]='\n' or not, s[lim-1]='\0'
s[i] = c;
}
if (c == '\n') // i < (lim-1), getchar() executed
{
s[i] = c; // '\n'
i++;
}
s[i] = '\0'; // the null character ends a string
if (c != EOF && c != '\n') // i == (lim-1) > 0
{
while ((c = getchar()) != EOF && c != '\n')
{i++;}
}
return i; // max(i) can exceed lim
}
// copy(); copy from[] into to[]; assume to[] is big enough
void copy(char to[], char from[])
{
int i;
for (i = 0; (to[i] = from[i]) != '\0'; i++)
{} // ends after copying '\0'
}
/*
gcc longline.c -o longline
./longline < longline.c // source file
Length: 77
// getLine(): read a line into s[] up to MAXLINE-1 chars, return total length
./longline < longline // binary file
Length: 4824
ELF // line contains '\0', which ends copy() and printf("%s")
*/
printf("%s", longest);
if (longest[max-1] != '\n')
{putchar('\n');} // line may not end with '\n'
because max may exceed MAXLINE. That is actually the reason getLine() returns a long instead of an int, as in the previous program (longest.c).
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
Exercise 1-17. Write a program to print all input lines that are longer than 80 characters.
#include <stdio.h> // for getchar(), putchar(), printf(), EOF
#define LENGTH 80 // minimum input line length printed (without '\0')
int getLine(char line[], int maxline); // getline() is declared in stdio.h
// int getLine(char [], int); // alternative declaration
void prnln(char line[]); // print line
// void prnln(char []); // alternative declaration
// print lines longer that LENGTH characters (including '\0')
int main()
{
int len; // current line length
char line[LENGTH+1]; // current input line
// +1 for ending '\0'
while((len = getLine(line, LENGTH+1)) > 0)
{ // line containing only '\n' has length 1
if (len > LENGTH) // len >= (LENGTH+1)
{prnln(line);} // here line[] does not end with '\n' (or EOF)
}
return 0;
}
// getLine(): read a line into s[] up to LENGTH chars, return length or LENGTH+1
int getLine(char s[], int lim) // return 0 at EOF
{
int c = EOF; // initialize
int i;
// getchar() is only executed if (i < (lim-1)):
for (i = 0; i < (lim-1) && (c = getchar()) != EOF && c != '\n'; i++)
{ // from 0 to lim-2; s[lim-2]='\n', s[lim-1]='\0'
s[i] = c;
}
if (c == '\n') // i < (lim-1), getchar() executed
{
s[i] = c; // '\n'
i++;
}
s[i] = '\0'; // the null character ends a string
if (c != EOF && c != '\n') // i == (lim-1) > 0
{ // in main() we need a condition to call prnln(), len > LENGTH:
return (i+1); // (i+1) == lim (LENGTH+1)
}
// else return i;
return i; // max(i) == (lim-1)
}
// prnln(); print line[], ending with first '\n' or EOF
void prnln(char line[])
{
int c;
printf("%s", line); // line[] does not end with '\n'
while ((c = getchar()) != EOF && c != '\n')
{putchar(c);}
putchar('\n'); // line may end with '\n' or EOF
}
/*
gcc prnln.c -o prnln
./prnln // input from the keyboard
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
// Ctrl+D in Linux, Ctrl+Z then Enter in Windows (EOF)
./prnln < prnln.c // source file
// getLine(): read a line into s[] up to LENGTH chars, return length or LENGTH+1
12345678901234567890123456789012345678901234567890123456789012345678901234567890
12345678901234567890123456789012345678901234567890123456789012345678901234567890
./prnln < prnln // binary file
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
Exercise 1-18. Write a program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines.
#include <stdio.h> // for getchar(), printf(), EOF
#define MAXLINE 1000 // maximum input line length
int getLine(char line[], int maxline); // getline() is declared in stdio.h
int trimline(char line[], int length);
// remove trailing blanks and tabs, delete blank lines
int main()
{
int len; // current line length
char line[MAXLINE]; // current input line
// line containing only '\n' has length 1:
while((len = getLine(line, MAXLINE)) > 0)
{
if (trimline(line, len) > 0) // nonempty line
{printf("%s\n", line);} // trimmed line doesn't end with '\n'
}
return 0;
}
// getLine(): read a line into s[] up to MAXLINE-1 chars, return length
int getLine(char s[], int lim)
{
int c = EOF; // initialize
int i;
// getchar() is only executed if (i < (lim-1)):
for (i = 0; i < (lim-1) && (c = getchar()) != EOF && c != '\n'; i++)
{ // from 0 to lim-2; s[lim-2]='\n', s[lim-1]='\0'
s[i] = c;
}
if (c == '\n') // i < (lim-1), getchar() executed
{
s[i] = c; // '\n'
i++;
}
s[i] = '\0'; // the null character ends a string
return i; // max(i) == (lim-1)
}
// remove trailing blanks, tabs, ending '\n', return new length
int trimline(char line[], int len)
{
int pos; // last nonempty position
pos = len-1; // last char before ending '\0'
if (line[pos] == '\n')
{
line[pos] = '\0'; // remove ending '\n'
pos--;
}
while (pos >= 0)
{
if (line[pos] == ' ' || line[pos] == '\t')
{
line[pos] = '\0';
pos--;
}
else break; // out of while()
}
if (pos < 0) {return 0;} // blank line
// else return (pos+1);
return (pos+1); // new length
}
/*
gcc trimfile1.c -o trimfile1
./trimfile1 // input from the keyboard
./trimfile1 < trimfile1.c // source file
./trimfile1 < trimfile1 // binary file
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
#include <stdio.h> // for getchar(), printf(), EOF
#define MAXLINE 1000 // maximum input line length
int getLine(char line[], int maxline); // getline() is declared in stdio.h
int trimline(char line[], int length);
// remove beginning and trailing blanks and tabs, delete blank lines
int main()
{
int len; // current line length
char line[MAXLINE]; // current input line
// line containing only '\n' has length 1:
while((len = getLine(line, MAXLINE)) > 0)
{
if (trimline(line, len) > 0) // nonempty line
{printf("%s\n", line);} // trimmed line doesn't end with '\n'
}
return 0;
}
// getLine(): read a line into s[] up to MAXLINE-1 chars, return length
int getLine(char s[], int lim)
{
int c = EOF; // initialize
int i;
// getchar() is only executed if (i < (lim-1)):
for (i = 0; i < (lim-1) && (c = getchar()) != EOF && c != '\n'; i++)
{ // from 0 to lim-2; s[lim-2]='\n', s[lim-1]='\0'
s[i] = c;
}
if (c == '\n') // i < (lim-1), getchar() executed
{
s[i] = c; // '\n'
i++;
}
s[i] = '\0'; // the null character ends a string
return i; // max(i) == (lim-1)
}
// remove beginning and ending whitespace, return new length
int trimline(char line[], int length) // length > 0
{
int i = 0, j, index;
while (i < length && (line[i] == ' ' || line[i] == '\t'))
{i++;}
if (i == length || line[i] == '\n')
{
line[0] = '\0'; // empty trimmed line
return 0;
}
// from here on non-empty trimmed line (from the beginning)
if (line[length-1] == '\n')
{j = length-2;} // remove ending '\n'
else {j = length-1;}
if (j >= i) // i >= 0
{
while (line[j] == ' ' || line[j] == '\t')
{j--;}
}
if (i > 0) // shift line to the beginning (remove beginning whitespace)
{
for (index = 0; index < j-i+1; index++)
{line[index] = line[index+i];}
}
line[j-i+1] = '\0'; // end line before trailing whitespace
return j-i+1; // new length
}
/*
gcc trimfile2.c -o trimfile2
./trimfile2 // input from the keyboard
Hello!
Hello!
Have a nice day!
Have a nice day!
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./trimfile2 < trimfile2.c // input from source file
./trimfile2 < trimfile2 // binary file
*/
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
*****************************************************************************************
Exercise 1-19. Write a function reverse(s) that reverses the character string s. Use it to write a program that reverses its input a line at a time.
#include <stdio.h> // for getchar(), putchar(), printf(), EOF
#define MAXLINE 1000 // maximum input line length
int getLine(char line[], int maxline); // getline() is declared in stdio.h
void reverse(char line[], int length);
// reverse each line
int main()
{
int len; // current line length
char line[MAXLINE]; // current input line
// line containing only '\n' has length 1:
while((len = getLine(line, MAXLINE)) > 0)
{
reverse(line, len);
printf("%s", line);
if (line[len-1] != '\n') {putchar('\n');}
}
return 0;
}
// getLine(): read a line into s[] up to LENGTH chars, return length
int getLine(char s[], int lim)
{
int c = EOF; // initialize
int i;
// getchar() is only executed if (i < (lim-1)):
for (i = 0; i < (lim-1) && (c = getchar()) != EOF && c != '\n'; i++)
{ // from 0 to lim-2; s[lim-2]='\n', s[lim-1]='\0'
s[i] = c;
}
if (c == '\n') // i < (lim-1), getchar() executed
{
s[i] = c; // '\n'
i++;
}
s[i] = '\0'; // the null character ends a string
return i; // max(i) == (lim-1)
}
// reverse a string of characters, knowing its length
void reverse(char line[], int len)
{
int start, end;
int temp; // temporary value
start = 0; // first char position in line[]
end = len-1; // last char before ending '\0'
if (line[end] == '\n')
{end--;} // do not put '\n' on position 0
while (start < end)
{
temp = line[start];
line[start] = line[end];
line[end] = temp;
start++, end--;
}
}
/*
gcc reverse.c -o reverse
./reverse // input from the keyboard
ana
ana
anna
anna
ab
ba
a
a
abc
cba
abcd
dcba
12345
54321
// Ctrl+D in Linux, Ctrl+Z then Enter in Windows (EOF)
./reverse < reverse.c // source file
./reverse < reverse // binary file
*/
int len;
for(len = 0; line[len] != '\0'; len++) {}