-3

Code1:

#include<stdio.h>
int main()
{
    unsigned short i, j, k;
    for (i = 0; i < 2; i++)
    {
        k = i * 4 + 4;

        for (j = k - 4; j < k; j++)
            printf("%hu ", j);

        putchar('\n');
    }

    return 0;
}

Output of Code1:

0 1 2 3 
4 5 6 7 

Remarks of Code1:

  1. Space after 3 and 7
  2. Newline after 7 (Stackoverflow has removed it)

Code2:

#include<stdio.h>
int main()
{
    unsigned short i, j, k;
    for (i = 0; i < 2; i++)
    {
        k = i * 4 + 4;
        for (j = k - 4; j < k; j++)
        {
            printf("%hu", j);

            if (j + 1 != k) putchar(' ');
        }

        if (i + 1 != 2) putchar('\n');
    }

    return 0;
}

Output of Code2:

0 1 2 3
4 5 6 7

Remarks of Code2:

  1. No space after 3 and 7
  2. No newline after 7

Additional remark of Code2:

The problem of Code2 is that the algorithm always compares two values in the if blocks and so Code2 is not efficient. I want to use Code1 and change these:

Code3

#include<stdio.h>
int main()
{
    unsigned short i, j, k;
    for (i = 0; i < 2; i++)
    {
        k = i * 4 + 4;

        for (j = k - 4; j < k; j++)
            printf("%hu ", j);

        printf("\b\n");
    }

    putchar('\b');
    return 0;
}

These do not show the same output of Code2 because \b does not erase anything.

My question:

Is there any standard way to do so what I've tried in Code3?

Remark of my question:

  1. I have searched the internet but have not determined the solution.
  2. Edit the question if it is not clear.

Edit: I don't know why my question is not useful or constructive. Though the above is an arbitrary small example, but performance might be an issue when processing very large amount of data. I thought that the way of removing character from console output might improve performance and there might be a specific way to do so. That's why I've asked the question. I could write the following codes in the answers. Now I've known via comments that removing character from console output is not possible because it is implementation dependent.

arnobpl
  • 1,126
  • 4
  • 16
  • 32
  • The question is not clear: do you aim for the output of code 2 ? If so why not organize the code in a way where you don't place '\n' and space characters you don't need there in the first place ? – count0 Dec 06 '13 at 14:39
  • 4
    Lesson 1: `'\b'` is just a byte sent to your stdout. If your stdout happens to go to a terminal, the terminal may respond by moving the caret backward (just like it responds to `'\t'` by moving the caret forward some number of times). Or the terminal may not. It depends on the implementation. Lesson 2: please do not prematurely optimize! The process of outputting characters to terminal DWARFS any time you could possibly spend in `if`s. –  Dec 06 '13 at 15:04

4 Answers4

1

The usual approach to this is to treat either the first or the last printf as a special case (outside of the loop):

for(ii=0; ii<2; ii++) {
  jj = 0;
  printf("%d", jj);      // first number printed without space.
  for(jj=1; jj<4; jj++) {
    printf(" %d", jj);   // include the space before the number printed
  }
  if(ii<2-1) printf("\n");
}

Obviously I simplified how the loops are constructed and what is printed - for simplicity. You could make the first printf statement

printf("\n%d", jj);

then you have a newline at the start of your output (often a good thing) and then you don't need the if statement later - you just don't have a newline printed at the end of the line (because it will be printed at the start...)

There are marginally more efficient ways of doing this that would involve no if statements at all - but these all come at the expense of less readable code. For example, here is a "no loop unrolling and no additional if statements" version of the code:

http://codepad.org/01qPPtee

#include <stdio.h>
int main(void) {
int ii, jj;
   ii = 0;
   while(1) {
      jj = 0;
      while(1) {
        printf("%d", jj);   // include the space before the number printed
        jj++;
        if(jj<4) printf("."); else break;
      }
      ii++;
      if(ii<2) printf("*\n"); else break;
    }
return 0;
}

Output:

0.1.2.3*
0.1.2.3

Basically I have taken the functionality of the for loop and made it explicit; I also use a . rather than a and "*\n" rather than "\n" to show in the printout that things behave as expected.

It does what you asked without extra evaluation of the condition. Is it more readable? Not really...

Floris
  • 45,857
  • 6
  • 70
  • 122
  • Your second code is efficient though less readable. I could make all the codes of the answers to my question. I want to know if there is any standard way to remove the last character from the console output what I have tried in **Code3**? – arnobpl Dec 06 '13 at 16:39
  • 1
    @arnobpl - Unfortunately "removing the character from console output" is implementation dependent - so there is no guaranteed "backspace and delete". I suspect this is a hangover from the days of teletypes - once the character was on paper you could backspace to overwrite, but you could not delete it. See Arkadiy 's comment. You might be interested in the question you inspired: http://stackoverflow.com/questions/20428158/putting-a-composite-statement-in-the-condition-of-a-for-loop – Floris Dec 06 '13 at 16:53
0

If it really bothers you, you can unroll your loops a little so that you treat the last item as a special case:

#include<stdio.h>
int main()
{
    unsigned short i, j, k;
    for (i = 0; i < 1; i++)
    {
        k = i * 4 + 4;
        for (j = k - 4; j < k - 1; j++)
        {
            printf("%hu ", j);
        }
        printf("%hu\n", j);
    }

    k = i * 4 + 4;
    for (j = k - 4; j < k - 1; j++)
    {
        printf("%hu ", j);
    }
    printf("%hu", j);

    return 0;
}
Adam Burry
  • 1,904
  • 13
  • 20
  • Your code is efficient but the code is larger. Is not there any standard way just to remove the last character from console output what I have tried in **Code3**? – arnobpl Dec 06 '13 at 16:32
0
#include <stdio.h>

int main(){
    unsigned short num = 0, to=8;

    while(num < to){
        printf("%hu", num++);
        if(num < to)
            putchar(num % 4 == 0 ? '\n' : ' ');
    }
#if 0
    do{
        printf("%hu", num++);
    }while(num < to && putchar(num % 4 == 0 ? '\n' : ' '));
#endif
    return 0 ;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • I think it would not be said to be a standard way it So if you how to write like a comment to say that you find out whether the last value is because the overlap. – BLUEPIXY Dec 06 '13 at 16:03
0

Well, to try to answer your question, here's how I would do it:

for (i = k = 0; i < 2; i++){
  if (i > 0) printf("\n");
  for (j = 0; j < 4; j++, k++){
    if (j > 0) printf(" ");
    printf("%d", k);
  }
}

I do it this way because I want to be sure every line but the first starts with a \n, and every item is separated by a space from the one before it. Also, I do not want the row and column position to be intimately tied to the content of what is being printed.

In terms of performance, keep in mind that these if statements cost about 1 cycle, while each character printed costs at least hundreds if not thousands. printf goes through many layers of system calls to interpret its format string, build a buffer, send the buffer to the system I/O routines, which then cause repainting and scrolling of the console window. Get the idea?

DO NOT WORRY about performance unless you know you have a problem. Then, don't guess. Use a diagnostic. Here's what I do.

Community
  • 1
  • 1
Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135