1) Implement -r 2) use a ring buffer (thereby avoiding any buffer overflow issue
ID: 3547357 • Letter: 1
Question
1) Implement -r
2) use a ring buffer (thereby avoiding any buffer overflow issues)
3) use only pointer notation (avoid a[i] notation)
Write a C program that will read data one
character at a time and output the results to standard output. Roughly,
your program should mostly copy the input stream to the output stream,
but it should delete all non-ASCII characters, 'make visible' the
'non-printing characters' from the input, but print only the LAST
72 characters of each line as it writes out the (new and improved) data.
Specifically, the changes that should be made to the incoming data are:
1) remove all non-printing characters (character codes 0 through 31,
and 127) and replace them with the same sort of codes the vi
editor uses. For example, the bell character (character code 7)
is replaced by the two printable characters "^" and "G" (G is the seventh
letter of the alphabet). Most of these are shown under the 'Ctrl char'
column of http://www.physics.udel.edu/~watson/scen103/ascii.html
If you have a copy of the Foster "C By Discovery" text (highly recommended,
and dirt cheap if you buy an older edition), Appendix-I also lists the ASCII
character set, and it shows all the proper two-character sequences that
should be used for the non-printing characters. There are two special cases:
Newlines should be replaced by a dollar sign ("$") and then an actual
newline. Replace the delete character by "^?" (Actually, if you use modular
arithmetic, the delete character does not have to be a special case.)
2) delete all non-ASCII characters (those with character codes 128 through 255).
3) once you have (internally) made the above changes, print only the LAST 72
[non-newline] characters (followed by a newline). Thus, a single Control-G
in the input line will account for two of those 72 characters ("^" and "G").
Regardless of the length of the line, the last visible character will
be a "$" -- except in the one (weird) case where the last 'line' of the
file does not end in a newline; in that case, there will be no "$" at
the end of that 'line' (and no newline, either).
4) Your p4 should also pay attention to command-line parameters. Invoked as:
p4
...your program MUST read from stdin, but if invoked as:
p4 somefilename
...then your program MUST instead fopen() "somefilename" for reading, and then
use getc() on this new filestream (in much the same way as you used getchar()
when reading from stdin). Indeed, getchar() is actually defined as getc(stdin),so it makes sense to just use getc() in every case.
Explanation / Answer
Implemented with visual studio 2010
unchecking the precompiled header option during starting of a new project.For this start a new project according to this http://dotnet.dzone.com/news/how-write-and-run-c-program .Detailed instruction for unchecking the precompiled header option is given in this link.Copy the program and try
// innov0.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
/* make the program flexible by making the maximum length
of line to display a compile-time variable
*/
#define MAXLINE 72
/* helper function: shift a string to the left within its
buffer to make room for a new character added on the
right
*/
void shiftleft (char *str, size_t move)
{
size_t i;
for (i=0; i<MAXLINE; i++) str[i] = str[i + move];
str[MAXLINE] = '';
}
int main (void)
{
int ch = 0, i = 0;
/* buffer needs to be MAXLINE plus one for the terminating
'', plus another one for possible overflow when we
convert an input byte to a two-character code */
char line[MAXLINE + 2];
int shipout = 0;
while (ch != EOF) {
ch = getchar();
/* the basic idea below is to divide the possible ch
values into categories that call for different
handling */
/* EOF -- prepare to ship out line */
if (ch == EOF) {
line[i] = '';
shipout = 1;
}
/* NULL byte or non-ASCII character -- ignore.
Note that you may not want to ignore 0 */
else if (ch == 0 || ch > 127) continue;
/* newline: prepare to ship out line */
else if (ch == ' ') {
line[i++] = '$';
line[i++] = ' ';
shipout = 1;
}
/* special character -- replace with code
You will need to modify this */
else if (ch < 26) {
line[i++] = '^';
line[i++] = 'A' + ch;
}
/* non-printing chars not handled above */
else if (ch < 32) continue;
/* regular ASCII character -- add to buffer */
else line[i++] = ch;
/* Now, have we filled the buffer yet? If so, shuffle
the content leftward, making room for new stuff.
We might be one character over the limit -- or
perhaps two, if the byte we just read expanded to
a two-character code in the output.
*/
if (i == MAXLINE - 1) {
shiftleft(line, 1);
i--;
}
else if (i == MAXLINE) {
shiftleft(line, 2);
i -= 2;
}
/* if we read EOF or newline, we should print the
line and reset the index i to zero
*/
if (shipout) {
line[i] = '';
printf("%s", line);
shipout = 0;
i = 0;
}
}
return 0;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.