remove trailing blanks - c

I'm working through k&r and I'm working on problem 1-18. Write a program to remove TRAILING blanks and tabs from each line of input and to delete entirely blank lines. My idea is to read in each line and have a count for the number of spaces. If it is the first blank print it using putchar. If there is a second blank do not print it and reset spaces to 0. Then continue to read through and remove spaces.
At the moment I have it to just print anything else it reads because I am attempting to do it bit by bit. Once I run this program I get two of these �� in the terminal. I think I am having problems nesting the if statement or the else statement incorrectly, I had some errors on there earlier. Am I going about the logic of removing blanks the correct way? If someone could point me in the right direction to fix the code I would be grateful.
#include <stdio.h>
main()
{
int c, i, spaces; /*c for input, i for counting*/
i = 0;
c = 0;
spaces = 0;
while ((c = getchar())!=EOF)
if(spaces = 0 && c == ' ')
++spaces;
putchar(c);
if(spaces >= 1)
spaces = 0;
else {
putchar(c);
}
}

Try with:
if(spaces == 0 && c == ' ')
{
++spaces;
putchar(c);
if(spaces >= 1)
spaces = 0;
}
else
{
putchar(c);
}
your indentation suggests you want the else branch to go with the first if, but as it is now, it corresponds with the inner if.
Also, spaces = 0 is an assignment, spaces == 0 is a comparison.

Read a string.
Find the end of the string using strlen() or similar method.
for(i=string_length-i; i>=0; i--) or use pointers if you prefer.
Break loop upon first non-space found.
Insert a null termination at first non-space+1.

Related

How can I make my program recognize tabs and turn them into normal spaces?

I am currently in the process of learning/ re-learning C. I had some trouble learning it last year in school. I am using a book and one of the exercises is asking to get excessive spaces and turn them into just one space. The problem is that I can't make it recognize tabs. I have looked for some on here already but they all deal with arrays. I can't use arrays. This is what I have so far.
int main()
{
int c;
c = getchar();
while (c != EOF)
{
if (c == ' ')
{
putchar(c);
for (c = getchar(); c == ' '; c = getchar())
;
}
else if (c == '\t')
putchar(' ');
putchar(c);
c = getchar();
}
}
So basically, the code starts off with getting a char value and putting it into "c". then while c is not EOF, if c equals the ASCII value of SPACE it is going to output it and enter a for loop. The for loop tests for additional spaces. c equals the following char and while c equals the ASCII value of SPACE, it the for loop will do nothing and it will iterate until all additional spaces are gone. The if statement works perfectly by the way.
Then I go into an else if which I am certain is wrong but it's my latest attempt. So for this I said else if c equals the ASCII value of tab (is that a thing? If not that might be what my error is) put down a space by using putchar(' '). I feel like that command might be wrong as well. After that statement it then exits the conditional, puts out the value then c now equals a new char and the loop continues.
Thanks!
EDIT: So right after posting this I realized, at least I think, my error is the putchar(c) at the bottom which is still printing out the tab regardless? Although I am still not sure how to approach the problem. One more thing is that these are the only commands I can use. The book still assumes I don't know how arrays and such work in C yet.
Although its a bit unclear on how subsequent spaces/tabs are to be handled, consider simply saving the previous character.
int previous = EOF;
int ch;
while ((ch = fgetchar()) != EOF) {
if (ch == '\t') { // or if (isblank(ch)) ...
ch = ' ';
}
if (previous != ' ') {
putchar(ch);
}
previous = ch;
}

K&R C Exercise 1-18 no output/debugging issues

I wrote the code below in Code::Blocks as a response to K&R C exercise 1-18:
Write a program to remove trailing blanks and tabs from each line of
input, and to delete entirely blank lines.
I meant it to remove the blanks and tabs (I haven't tackled the blank line part yet). The while loop correctly saves input to the character array ip, however, the rest of the code doesn't seem to be working as EOF doesn't illicit any output at all.
#include <stdio.h>
#define MAXLINE 1000
main(){
int c, z;
char ip[MAXLINE];
z = 0;
while ((c = getchar()) != EOF) {
ip[z] = c;
++z;
}
for (z = 0; ip[z] == ' ' || ip[z] == '\t'; ip[z] = ip[z + 1]);
printf("%s", ip);
}
I was trying to use this issue as a way to learn the debugger, but after I add a breakpoint at line 14, open the watches window, and press the start arrow, nothing happens. No yellow arrow appears at my break point, my step options are greyed out, and neither my variable names nor their values show up in the watch window.
Advice on fixing my code is appreciated, but what I really want to know is what I'm doing or not doing that is preventing the debugger from helping me.
If you aren't seeing any output, then this is probably because your program is stuck in the for loop: for (z = 0; ip[z] ..., which happens if the string ip starts with two consecutive spaces and/or tabs.
The algorithm for removing a certain character is as such:
Have two variables that index a position in the string, destination and source. The code will be inside an outer loop. Source index will iterate in an inner loop until it finds a character that isn't one of the characters that have to be removed or the null character. Then the character from source index is assigned to destination index. The code then checks if source index reached a null character and breaks the outer loop if it did. Both indexes get incremented, the outer loop is then repeated.
In pseudo code:
remove = '\t'
string
source = 0
destin = 0
while
while string at source equals remove and not-equals null character
source++
string at destin = string at source
if string at source equals null character
break
source++
destin++

Word count in C?

I have a problem with counting words in std. I use the same method when I count words in files there works OK.
My method is as follows: We read until ctrl+d. If the next character is a line return, increase new_lines. Otherwise, we increase the words because the next method (last if) doesn't read until first space and I lost first word. In the end If the current character is a space and next element is something other than a space, increase words.
Now I'm going to explain about problem. If I have empty line program increase words but why I use second if for this. If I don't have empty lines program work.
int status_read=1;
while (status_read > 0){ // read to end of file
status_read = read(STDOUT_FILENO, buff, 9999); // read from std
for (i = 0; i < status_read ; i++) { // until i<status_read
if (buff[i] == '\n') {
new_lines++;
if (buff[i+1]!='\n')
wordcounter++;
}
if (buff[i] == ' ' && buff[i+1]!=' ')
wordcounter++;
}
}
As #FredLarson commented, you are trying to read from standard out, not standard in (that is, you should be using STDIN_FILENO, not STDOUT_FILENO).
If I have empty line program increase words but why I use second if
for this. If I don't have empty lines program work.
That's due to
if (buff[i] == '\n') {
new_lines++;
if (buff[i+1]!='\n')
wordcounter++;
}
- to solve this problem, just don't increment wordcounter here - replace the above with
if (buff[i] == '\n') ++new_lines;
Otherwise,
we increase the words because the next method (last if) doesn't read
until first space and I lost first word.
To avoid the problem of losing the first word on a line, as well as that with buff[i+1] (see M Oehm's comments above), I suggest changing
if (buff[i] == ' ' && buff[i+1]!=' ')
wordcounter++;
to
if (wasspace && !isspace(buff[i])) ++wordcounter;
wasspace = isspace(buff[i]);
- wasspace being defined and initialized to int wasspace = 1; before the file read loop.

what is wrong with the while loop here ? C basics

I am trying to count the number of letters of a word before the space. For eg. "Hello how" is my input string and I am trying to count the number of letters in the first word.
#include<stdio.h>
#include<string.h>
int main()
{
char a[30];
int count = 0;
printf("Enter the string.\n"); // Enter hello how as string here.
gets(a);
for ( i = 0; a[i] != '\0'; i++ )
{
while( a[i+1] != ' ' )
count++;
}
printf("%d\n",count);
}
This is a small part of a bigger code, I am actually expecting the value of count to be 5 but it gets into some sort of infinite loop which I am unable to figure out. If I use if instead of while , I get the expected answer. I know gets is not very reliable and I will not use once I get better at programming so it will be kind of you to post your answer about the loop instead of gets. Thank You.
The NUL character is written with a backslash (\), not forward slash (/).
for (i = 0; a[i] != '\0'; i++)
Furthermore, the inner loop will not terminate because you're not incrementing i.
while (a[i] != ' ') {
i++;
count++;
}
Actually, you should not really have two loops. One loop is all you need.
for (i = 0; a[i] != '\0' && a[i] != ' '; i++) {
count++;
}
The expression within the while statement does not depend on count. So with every iteration of the while loop the count gets incremented, but that has no influence on the while conditional, hence it will loop ad infinitum or never, depending on the character at a[i+1].
In addition to that, the conditional statement for the for loop is not written correctly either. The string escape for a NUL character is \0 (backslash). Or you can just compare against a 0 literal, which has exactly the same outcome (though when it comes to the subtleties of C it does not mean exactly the same, but that's splitting hairs).
Use '\0' instead of '/0' in the for loop condition and also the while loop condition will never be false because i remains the same

Counting words in a string?

Hello for this program I am supposed to count the number of words in a string. So far, I have found out how to find the number of characters in a string but am unable to figure out how to turn the letters that make a word, and count it as 1 word.
My function is:
int wordcount( char word[MAX] ){
int i, num, counter, j;
num = strlen( word );
counter = 0;
for (i = 0; i < num; i++)
{
if (word[i] != ' ' || word[i] != '\t' || word[i] != '\v' || word[i] != '\f')
{
}
}
return counter;
}
I tried some variations, but the middle part of the if statement is where I am confused. How can I count the number of words in a string? Testing for this tests if the string has multiple spaces like "Hello this is a string"
Hints only since this is probably homework.
What you're looking to count is the number of transitions between 'word' characters and whitespace. That will require remembering the last character and comparing it to the current one.
If one is whitespace and the other is not, you have a transition.
With more detail, initialise the lastchar to whitespace, then loop over every character in your input. Where the lastchar was whitespace and the current character is not, increase the word count.
Don't forget to copy the current character to lastchar at the end of each loop iteration. And it should hopefully go without saying that the word count should be initialised to 0.
There is a linux util 'wc' that can count words.
have a look (it includes some explanation and a sample):
http://en.literateprograms.org/Word_count_(C)
and a link to the source
http://en.literateprograms.org/index.php?title=Special:DownloadCode/Word_count_(C)&oldid=15634
When you're in the if part, it means you're inside a word. So you can flag this inword and look whether you change from out of word (which would be your else part) to inword and back.
This is a quick suggestion — there could be better ways, but I like this one.
First, be sure to "know" what a word is made of. Let us suppose it's made of letters only. All the rest, being punctuation or "blanks", can be considered as a separator.
Then, your "system" has two states: 1) completing a word, 2) skipping separator(s).
You begin your code with a free run of the skip separator(s) code. Then you enter the "completing a word" state which you will keep until the next separator or the end of the whole string (in this case, you exit). When it happens, you have completed a word, so you increment your word counter by 1, and you go in the "skipping separators" state. And the loop continue.
Pseudo C-like code:
char *str;
/* someone will assign str correctly */
word_count = 0;
state = SKIPPING;
for(c = *str; *str != '\0'; str++)
{
if (state == SKIPPING && can_be_part_of_a_word(c)) {
state = CONSUMING;
/* if you need to accumulate the letters,
here you have to push c somewhere */
}
else if (state == SKIPPING) continue; // unneeded - just to show the logic
else if (state == CONSUMING && can_be_part_of_a_word(c)) {
/* continue accumulating pushing c somewhere
or, if you don't need, ... else if kept as placeholder */
}
else if (state == CONSUMING) {
/* separator found while consuming a word:
the word ended. If you accumulated chars, you can ship
them out as "the word" */
word_count++;
state = SKIPPING;
}
}
// if the state on exit is CONSUMING you need to increment word_count:
// you can rearrange things to avoid this when the loop ends,
// if you don't like it
if (state == CONSUMING) { word_count++; /* plus ship out last word */ }
the function can_be_part_of_a_word returns true if the read char is in [A-Za-z_] for example, false otherwise.
(It should work If I have not done some gross error with the abetment of the tiredness)

Resources