Reputation: 11
I'm doing some exercises from "C Programming Language" and can't figure out what is going on to give me certain output. Not really a roadblock because I got the output I wanted, but I don't understand why changing a certain piece of my code actually gave me the output I wanted. Was just looking for an explanation.
Here is the code that works the way I want it to. The part I am not understanding is the s[++i] = ' ';
in the 'k' for loop. Before I used s[++i]
, I used:
s[i] = ' ';
++i;
Which would only put 1 space in the array, no matter how many times that k loop ran.
Then, just for testing, I placed ++i;
above s[i] = ' ';
and not a single space was included in my output.
#include <stdio.h>
#define MAXLINE 1000
#define TABSTOP 5
/* Write a program "detab" that replaces tabs in the input with a proper
number of blanks to space to the next tab stop. Assume a fixed set of tab
stops, say every n columnns. Should n be a variable or a synbolic parameter? */
int main() {
char c;
int i, j;
int modTabStop, numTabs, k;
char s[MAXLINE];
i = 0;
while((c = getchar()) != EOF) {
if(c == '\t') {
modTabStop = i % TABSTOP;
numTabs = TABSTOP - modTabStop;
for(k = 0;k <= numTabs; ++k)
s[++i] = ' ';
}
else if(c == '\n') {
;
}
else {
s[i] = c;
++i;
}
}
for(j = 0;j <= i;++j)
printf("%c", s[j]);
return 0;
}
I'm just wondering why s[++i]
worked and none of the others did. My expected output is defined in the comment above the main function. But just for clarification, I was using the test string "the(tab)dog". When it works correctly, only 2 spaces should be placed in place of the tab in between "the" and "dog" because my tab stop is 5 and "the" is three letters long ("the(space)(space)dog"). If I put ++i;
after s[i] = ' '
, then I get a single space in between ("the(space)dog"). And if I place it before, I get no spaces ("thedog").
I just want to make sure I understand all this fully before moving on. Thanks guys!
Upvotes: 1
Views: 1599
Reputation: 311126
For starters this loop
for(k = 0;k <= numTabs; ++k)
^^^
is incorrect. It should look like
for(k = 0;k < numTabs; ++k)
^^^
In this case exactly numTabs spaces will be inserted in the array,
This assignment
s[++i] = ' ';
is also incorrect because the character at the position i
is not changed. The position is skipped due to the pre-increment operator ++i
.
You should write instead
s[i++] = ' ';
So finally the loop will look like
for(k = 0;k < numTabs; ++k)
s[i++] = ' ';
Pay attention to that this loop
while((c = getchar()) != EOF) {
is incorrect.
You should write instead
while( i < MAXLINE && ( c = getchar() ) != EOF && c != '\n' ) {
or at least like
while( i < MAXLINE && ( c = getchar() ) != EOF ) {
In the last case you should write within the loop
else if(c == '\n') {
s[i++] = ' ';
}
Otherwise if you are entering several statements they will not be separated.
In the first case this if statement shall be removed.
And instead of the declaration
char c;
you should use the declaration
int c;
because the type char can behave as the type unsigned char (depending on the compiler options). And in this case the comparison c != EOF
will be always true.
Upvotes: 4
Reputation: 1302
Consider the code:
for(k = 0;k <= numTabs; ++k)
s[i] = ' ';
++i;
this is equivalent to
for(k = 0;k <= numTabs; ++k){
s[i] = ' ';
}
++i;
as only the first statement is in the for loop when using no braces.
This then means: write space to s[i]
for numTabs
-times, then increment i
. Effectively writing one space.
Similar:
for(k = 0;k <= numTabs; ++k)
++i;
s[i] = ' ';
would increment i
for numTabs
times and then write a space. This leaves numTabs
characters of gibberish in the array and probably a terminating NULL.
The solution is simple: Use braces
Upvotes: 1
Reputation: 445
There's a major difference between
s[i]
i++;
and
s[++i]
Before explaining, let me simplify the first form into s[i++]
so you have
s[i++]
and
s[++i]
which I believe makes things more clear, this is the difference between pre-increment and post-increment.
The difference is that pre-increment s[++i]
increments the value of i
before injecting it into the expression which is the array access operator in our case. While post-increment injects the value of i first into the array access operator, then increments it later on just like what you originally did in the expanded two lines form.
Upvotes: 3