What should i do in this program. I cant understand.
The question is as : Write a program detab that replaces tabs in the input with the proper number
of blanks to space to the next tab stop. Assume a fixed set of tab stops, say every n columns.
Should n be a variable or a symbolic parameter?
I started by replacing the tabs ('\t') with space (' ').
But i guess this is the wrong approach.
please suggest ?
and btw what should n be? variable or symbolic parameter?
code so far:
#include<stdio.h>
#define TAB 5
int main() {
int i, c;
while((c = getchar()) != EOF) {
if(c == '\t') {
for(i = 0; i < TAB; ++i)
putchar(' ');
} else
putchar(c);
}
return 0;
}
In all the questions posted for this exercise i couldn't understand the meaning.
This is my final code, please tell me if it has any problems / bugs. I think it is working as it should..
thanks to #Nit, #Chrono Kitsune , #dasblinkenlight and all the others who helped.
#include<stdio.h>
#define TAB 8
int main() {
int c, count = 0, space = 0;
while((c = getchar()) != EOF) {
if(c == '\t') {
space = (TAB - (count % TAB));
while(space > 0){
putchar(' ');
count++;
space--;
}
}
else{
putchar(c);
++count;
}
if(c == '\n')
count = 0;
}
return 0;
}
What you are doing is not what the exercise wants you to do: rather than inserting a fixed number of spaces for each tab, you should be inserting a different number of spaces depending on how much has been printed on the line so far.
It does not matter how you take the number of spaces per tab - the way you made it a preprocessor constant is perfectly fine. However, rather than producing TAB spaces regardless of where the '\t' has been found, you program needs to count how much "regular" characters have been printed, and count how many spaces are needed when it sees '\t'.
Make a variable count for characters printed so far. Initialize it to zero, and then reset it back to zero each time you see a '\n' character. When you call putchar, also make count++.
Now when you see a tab '\t' compute how far you are form the next tab stop. The expression for that is
TAB - (count % TAB)
That is how many spaces you need to print.
This should be enough information for you to go back and fix your program - I think you need to write only five additional lines of code (not counting lines for curly braces that you would need to insert) in order to finish this exercise.
The first step is to understand the problem. As I read it over and over for several times at first I couldn't understand what exactly it wants me to do. It's because some concepts weren't clear or familiar to me before I searched for more information about tab. First, what is a tab and what is a tab stop exactly? A tab is a character represented by the escape sequence \t in many contexts. Just like other characters such as letters or digits, it's a character, but with special usage, so it's not a wide space or 4 or 8 spaces as it appears to be. Being displayed like a wide space or 4 or 8 spaces is just what it's designed for, which aligns each tab-delimited group of texts on multiple lines to make the region look like a table, but underneath on the level the software sees it's just a character. Tab stops are positions on the line where the cursor goes when the Tab key is pressed. These positions are fixed on the line according to the width or number of characters (or columns, all referring to the same concept) with which the Tab character is displayed. For example, on Windows Notepad the default width for Tab is 8 characters, and when you type Tab key the cursor would move behind the 8th, 16th, 24th... character. You can type 0s on the first line to see the effect more clearly:
00000000000000000000000000000000
Ivan Hello World
This is a table
delimited by tab
Now reading the problem over again it's clear to me that it's about replacing the Tab characters with spaces while maintaining the original table look. Then you can start writing your code to calculate how many spaces are needed for each Tab. Here's my complete code for this exercise:
#include <stdio.h>
#define MAX_LENGTH 1000
#define LINE_NUM 100
#define TAB_WIDTH 8
int readLine(char line[], int maxLength);
void copy(char from[], char to[]);
void detab(char line[], char result[]);
main() {
printf("Input: \n");
char lines[LINE_NUM][MAX_LENGTH];
char line[MAX_LENGTH];
char result[MAX_LENGTH];
int lineId = 0, length = 0;
while ((length = readLine(line, MAX_LENGTH)) != 0) {
detab(line, result);
copy(result, lines[lineId]);
lineId++;
}
printf("Output: \n");
for (int i = 0; i <= lineId; i++) {
printf("%s\n", lines[i]);
}
}
int readLine(char line[], int maxLength) {
char ch;
int length = 0;
while ((ch = getchar()) != EOF && ch != '\n' && length < maxLength) {
line[length] = ch;
length++;
}
if (ch == '\n') {
line[length] = '\0';
}
return length;
}
void copy(char from[], char to[]) {
int i = 0;
while (from[i] != '\0') {
to[i] = from[i];
i++;
}
to[i] = '\0';
}
void detab(char line[], char result[]) {
int i = 0;
char ch;
int column = 0;
int spaces;
int nextTabStop;
while ((ch = line[i++]) != '\0') {
if (ch == '\t') {
spaces = TAB_WIDTH - column % TAB_WIDTH;
nextTabStop = column + spaces;
for (; column < nextTabStop; column++) {
result[column] = ' ';
}
} else {
result[column] = ch;
column++;
}
}
result[column] = '\0';
}
First, try to get familiar with '\t' (TAB character) and see what happens when you print
'\t' + ','
'.' + '\t' + ','
'..' + '\t' + ','
And so on. You will see that there is a fixed number of initial '.'s in which the ',' character after '\t' is on the same position, this means that the '\t' length is not fixed, so if you try to replace it with a fixed number of ' ' characters (white spaces), the output will be different from the input.
Understanding that, your task is to create a program that replaces all '\t' characters with white spaces, so you have to calculate the number of necessary white spaces to print for each '\t' char you read. This is what I've done so far.
#include <stdio.h>
#define WSPT 8 // white spaces per tab
main () {
int c, counter;
counter = 0; // distance from the previous tab stop
while((c = getchar()) != EOF) {
if(c == '\t') {
for(int i = 0; i < WSPT - counter; ++i)
putchar(' '); // print white spaces until reach the next tab stop
counter = 0; // you are again at the start of a tab stop
} else {
putchar(c);
if(c != '\n')
counter = (counter + 1) % WSPT; // move 1 step
else
counter = 0; // you are again at the start of a tab stop
}
}
}
Okay, his is actually a very simple question and I'm not sure why everyone is making it more complicated than it is. We need to simply replace tab's with the necessary number of blanks so the resulting output looks no different than if there was a tab there.
No need for a million lines of code... a few will do...
#include <stdio.h>
/* A program *detab* that replaces tabs in the input with the proper number of blanks to space to the next tab stop. Assuming a fixed set of tabstops, say every n columns */
#define TAB_WIDTH 4 // tab width on particular machine
int main()
{
int c;
int i = 0;
while((c = getchar()) != EOF) {
if(c != '\t')
putchar(c);
else
while(i < TAB_WIDTH - 1){
putchar(' ');
i++;
}
}
}
why so complicated stuffs..just do this
#include <stdio.h>
int main()
{
int c, tab=6, count=0;
while((c=getchar())!=EOF)
{
count++;
if (c=='\t')
{
for (int i=count; i%(tab+1)!=0; i++) putchar(' ');
}
else putchar(c);
if(c=='\n') count=0;
}
}
Related
I am new to C and working on homework. I got most work done, but I can't pass all test cases that used by my professor. He refuses to post cases being used in the auto grader.
What would be the cases that I have missed?
Any clue will be appreciated!!!
Write a program to remove all the blank characters (space and tab) in a line.
Then, count the number of appearances of each character.
Input
A single line with a maximum length of 5000 characters
Output
First line: The line after removing all the blank characters.
If the line is empty, don’t print anything in the output.
Next lines: Each line contains a character that appears in the line and its count.
Note that, the characters must appear according to their ASCII number order. (http://www.asciitable.com)
#include <stdio.h>
int main (){
int c = 0;
int characters[128] = {0}; // subscripts for the ASCII table
int count = 0; // number of characters been reading in
while(count < 5001 && (c = getchar()) != EOF) {
// 9 -> TAB on ASCII, 32 -> Space on ASCII
if (c != 9 && c != 32) {
putchar(c);
characters[c]++;
count++;
}
}
fflush(stdout);
printf("\n");
for (int i = 0; i < 128; i++) {
if (characters[i] != 0) {
printf("%c %d\n", i, characters[i]);
}
}
return 0;
}
Again, any help will be really appreciated!
Update:
The code has been corrected.
Probably you don't want to write
characters[index] = 0;
What you want instead is probably
text[index] = 0;
I am reading the C programming language book Dennis M. Ritchie and
trying to solve this question:
Write a program to print a histogram of
the lengths of words in
its input. It is easy to draw the histogram with the bars horizontal; a vertical
orientation is more challenging.
I think my solution works, but the problem is that if I don't press EOF, the terminal won't show the
result. I know that the condition specifies that exactly, but I am
wondering whether there is any way to make the program terminate after
reading a single line? (Sorry if my explanation of the problem is a bit shallow. Feel free to ask more.)
#include <stdio.h>
int main ()
{
int digits[10];
int nc=0;
int c, i, j;
for (i = 0; i <= 10; i++)
digits[i] = 0;
//take input;
while ((c = getchar ()) != EOF) {
++nc;
if (c == ' ' || c=='\n') {
++digits[nc-1];
//is it also counting the space in nc? i think it is,so we should do nc-1
nc = 0;
}
}
for (i = 1; i <= 5; i++) {
printf("%d :", i);
for (j = 1; j <= digits[i]; j++) {
printf ("*");
}
printf ("\n");
}
// I think this is a problem with getchar()
//the program doesn't exit automatically
//need to find a way to do it
}
You could try to make something like
while ((c = getchar ()) != EOF && c != '\n') {
and then adding a line after the while loop to account for the last word:
if (c == '\n') {
++digits[nc-1];
nc = 0;
There is also another problem inside your program. ++digits[nc-1]; is correct, however, for the wrong reason. You should make it because an array starts at zero, i.e. if you have an array of length 10, it will go from 0 to 9, so you should count the length of the words and then add one to the position of the array length - 1 (as there are no words of length zero). The problem is that you are still counting the blank spaces or the newline characters inside the length of a word, so if you have two blank spaces after a word of length 4, the program will add to the array a word of length 5 + a word of length 1. To avoid this, you should do something like this:
while ((c = getchar ()) != EOF) {
if ((c == ' ' || c == '\n' || c == '\t') && nc > 0) {
++digits[nc-1]; // arrays start at zero
nc = 0;
}
else {
++nc;
}
}
I'm trying K&R exercise 1-29 and honestly I'm stumped by what my program is doing. Upon inputting a small text file with gcc, the program just runs forever as if there's an infinite loop. Reading through my loops again I can't see any obvious mistakes, so I tried to print different variables to see what's happening, but nothing's printing to the command line - even the variable i from the very first for loop, not even once. Here's my code:
#include <stdio.h>
#define tabStop 10
#define maxInput 1000
int main(){
int i, c, b;
int m, t = 0;
int index, index2;
char input[maxInput];
int nonBlank;
for (i = 0; i<maxInput-1 && (c=getchar()) != EOF; ++i){
if (c != ' '){
input[i] = c;
}
else {
index = i; /*stores location in character array at start of blanks*/
for (b = 0; c == ' '; ++b, ++i); /*counts the number of blanks (b) until the next non-blank character*/
nonBlank = input[i]; /*saves the first seen non-blank character to be re-added later (as getchar() will have taken it in from input and will now stay at that point of the input)*/
index2 = i; /*stores location in character array at end of blanks*/
if (b >= tabStop){ /*if the tab space fits inside the number of blanks, otherwise there is nothing to be done*/
while (t < b){
t += tabStop;
++m;
}
for (int x = 0, i = index; i != index2 && x <= m; ++i, ++x){ /*loops over the number of tabs to be added starting from the first blank in the array found up until the first non-blank*/
input[i] = '\t';
}
while (i != index2){ /*if i did not reach index2 before x surpassed m, there exist remaining spaces to be filled with blanks*/
input[i] = ' ';
++i;
}
}
input[i] = nonBlank; /*puts the first seen non-blank character into place, as getchar() has already covered it and so it wouldn't otherwise be added like other non-blanks*/
}
}
input[i] = '\0';
printf("%s", input);
return 0;
}
Here's the inputted text file:
hello there world
K&R C Exercise 1-9 states:
Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank.
I have nearly solved this exercise, but the code I've written (see below) always prints an extra space before the first nonspace character. So input that looks like this
X(space)(space)X(space)(space)X(space)(space)X
results in output that looks like this
(space)X(space)X(space)X(space)X
#include <stdio.h>
int main()
{
int c; //current input character
int s; //consecutive input space counter
c = getchar();
s = 0;
while ((c = getchar()) != EOF){
if (c == ' '){
++s;
if (s == 1) //uses the counter to print only the
putchar(' '); //first space in each string of spaces
}
else {
putchar(c);
if (s != 0) //resets the space counter when it
s = 0; //encounters a non-space input character
}
}
return 0;
}
Why does my code always print a leading space when I run it?
How can I modify this code to print the first input character first instead of a leading space?
Do not throw away the first char. #David Hoelzer
// Commented out
//c = getchar();
s = 0;
while ((c = getchar()) != EOF){
Also note unbalanced } near return 0;
I've been stuck at this problem:
Write a Program to remove the trailing blanks and tabs from each input line and to delete entirely blank lines.
for the last couple of hours, it seems that I can not get it to work properly.
#include<stdio.h>
#define MAXLINE 1000
int mgetline(char line[],int lim);
int removetrail(char rline[]);
//==================================================================
int main(void)
{
int len;
char line[MAXLINE];
while((len=mgetline(line,MAXLINE))>0)
if(removetrail(line) > 0)
printf("%s",line);
return 0;
}
//==================================================================
int mgetline(char s[],int lim)
{
int i,c;
for(i = 0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
s[i] = c;
if( c == '\n')
{
s[i]=c;
++i;
}
s[i]='\0';
return i;
}
/* To remove Trailing Blanks,tabs. Go to End and proceed backwards removing */
int removetrail(char s[])
{
int i;
for(i = 0; s[i] != '\n'; ++i)
;
--i; /* To consider raw line without \n */
for(i > 0; ((s[i] == ' ') || (s[i] == '\t')); --i)
; /* Removing the Trailing Blanks and Tab Spaces */
if( i >= 0) /* Non Empty Line */
{
++i;
s[i] = '\n';
++i;
s[i] = '\0';
}
return i;
}
I am using gedit text editor in debian.
Anyway when I type text into the terminal and hit enter it just copies the whole line down, and if I type text with blanks and tabs and I press EOF(ctrl+D) I get the segmentation fault.
I guess the program is running out of memory and/or using memory 'blocks' out of its array, I am still really new to all of this.
Any kind of help is appreciated, thanks in advance.
P.S.: I tried using both the code from the solutions book and code from random sites on internet but both of them give me the segmentation fault message when EOF is encountered.
It's easy:
The mgetline returns the buffer filled with data you enter in two cases:
when new line char is encountered
when EOF is encountered.
In first case it put the new line char into the buffer, in the latter - it does not.
Then you pass the buffer to removetrail function that first tries to find the newline char:
for(i=0; s[i]!='\n'; ++i)
;
But there is no new line char when you hit Ctrl-D! Thus you get memory access exception as you pass over the mapped memory.