ubernoob1010
ubernoob1010

Reputation: 11

Difference between s[++i]; and s[i]; ++i;

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

Answers (3)

Vlad from Moscow
Vlad from Moscow

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

Burdui
Burdui

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

mohkamfer
mohkamfer

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

Related Questions