0

I know scanf is bad and all, but we won't be testing for invalid input on this (assume always valid). However, when I do a call to promptPlayer() which has the scanf call, output to the console stops (which makes no sense because all the output should be in the console before the calls to scanf are even made. Input should be a set of coordinates separated by whitespace (as shown in output).

Here is the code (the important stuff):

othello.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "othello_engine.h"

int main(int numArgs, const char *args[]) {

    // -------------------------- Initialize the Othello routine --------------------------- //

    // Create the board
    int size = atoi(args[2]);
    char board[size][size];

    // Display game start message
    if (args[4][0] == 'B' || args[4][0] == 'b')
        printf("Othello game with a %dx%d board - Player %d with black disc to start\n\n", size, size, atoi(args[3]));
    else
        printf("Othello game with a %dx%d board - Player %d with white disc to start\n\n", size, size, atoi(args[3]));

    // Initially display the game board
    displayBoard(size, size, board);

    // --------------------------- Start the game through user input --------------------------- //

    Coordinate placed = promptPlayer(1);

    printf("Place at [%d,%d].\n", placed.x, placed.y);

    Coordinate placed2 = promptPlayer(1);

    printf("Place at [%d,%d].\n", placed2.x, placed2.y);

    return EXIT_SUCCESS;
}

othello_engine.c

#include "othello_engine.h"
#include <stdio.h>

void displayBoard(int size, int size2, char board[size][size2]) {

    // Print the column numbers
    printf(" ");
    for (int i = 0; i < size; i ++) {
        printf(" %d", (i+1));
    }
    printf("\n");

    // Print the rest of the matrix, including row numbers
    for (int i = 0; i < size; i ++) {
        printf("%d", (i+1));
        for (int j = 0; j < size2; j ++) {
            if (board[i][j] != 'B' && board[i][j] != 'W') printf(" -");
            else printf(" %c", board[i][j]);
        }
        printf("\n");
    }
    printf("\n\n");
}

Coordinate promptPlayer(int player) {

    Coordinate desiredLocation;
    printf("Player %d's turn (enter row and column): ", player);
    scanf("%d %d", &desiredLocation.x, &desiredLocation.y);
    //scanf("%*[^\n]%*c");

    return desiredLocation;
}

Lastly, othello_engine.h

#ifndef OTHELLO_ENGINE_H_
#define OTHELLO_ENGINE_H_

typedef struct {
    int x;
    int y;
} Coordinate;

#endif /* OTHELLO_ENGINE_H_ */

/*
 * Displays the Othello board and row/column numbers.
 */
void displayBoard(int size, int size2, char board[size][size2]);

Coordinate promptPlayer(int player);

Here is the output: Basically the output stream is halted for the entire program until after all scanfs have been evaluated. I have no idea what is causing this.

1 2 // This is the first scanf input
3 4 // This is the second set
Othello game with a 6x6 board - Player 1 with black disc to start

  1 2 3 4 5 6
1 - - - - - -
2 - - - - - -
3 - - B W - -
4 - - W B - -
5 - - - - - -
6 - - - - - -


Player 1's turn (enter row and column): Place at [1,2]. // Here is where the first scanf's values are output
Player 1's turn (enter row and column): Place at [3,4]. // Here is the second set

It really doesn't make any sense. Everything prints out perfectly until the promptPlayer method is called - the values are being received correctly, so I don't really see the problem... Seems like scanf stops console output (magically?) until the values are input - then it prints everything to the console all at once. I just know it's something really obvious.

Chris Cirefice
  • 5,475
  • 7
  • 45
  • 75
  • Just in case; if you are using Eclipse this SO Question is relevant: http://stackoverflow.com/questions/13035075/printf-not-printing-on-console. So try running your compiled exe outside of your editor tool as it seems its also a problem in some other editors. – miltonb Sep 24 '13 at 00:09
  • 1
    Since you don't check the return value from `scanf()` in `promptPlayer()`, you don't know whether it is working or not. Check that. Also consider using `fgets()` to read a line and then `sscanf()` to analyze it — rather than relying on `scanf()` which will cheerfully accept multiple inputs on a single line or a single input over multiple lines, which can lead to confusion too. – Jonathan Leffler Sep 24 '13 at 00:28
  • Jonathan, I validated the return values of that function by printing them (noted in the output). But this is an Eclipse IDE bug. The program as a whole works fine through CMD on Windows, and I recall seeing this bug a year ago when I last programmed in C. As miltonb said, the bug was marked as WONT-FIX, so it's just something Eclipse IDE-users are going to have to deal with! – Chris Cirefice Sep 24 '13 at 00:31
  • Yeah, so I see. The advice I gave still stands (it is a good idea), but I can see how the problem is in Eclipse. The Eclipse bug mentions `setvbuf(stdout, NULL, 0, _IONBF);`. That can lead to bad performance (but correct behaviour). It would be worth trying `_IOLBF` (line buffering) instead of `_IONBF` (no buffering) — but you'd still have to use `fflush(stdout)` or `fflush(0)` before input statements to get the prompt to appear. Other output would appear at the end of each line. – Jonathan Leffler Sep 24 '13 at 00:38
  • I see. I'll check that out after I turn in this project. Since I would actually like to practice C++ (same issue was present), any type of workaround would be nice to get Eclipse to behave as expected! – Chris Cirefice Sep 24 '13 at 00:43

2 Answers2

3

I have run a small bit of your code promptPlayer and to my eye can not observe anything actually wrong with your code, its doing what is expected. I think this is a problem outside of your code likely to be the editor you are using and its interaction with console as for example Eclipse or Mintty

Try running your compiled exe outside of your editor tool and find out if you get the same problem.

Assuming it is something like the above then adding the following code to flush the output could also resolve the problem:

    Coordinate desiredLocation;
    printf("Player %d's turn (enter row and column): ", player);
    fflush(stdout);
    scanf("%d %d", &desiredLocation.x, &desiredLocation.y);
Community
  • 1
  • 1
miltonb
  • 6,905
  • 8
  • 45
  • 55
  • This answer partially solved the problem. I added `fflush(stdout)` to the start and end of the `promptPlayer` function. Not perfect, but also not what I wanted. It turns out that your comment on my question was true, and I do remember seeing this about a year ago when I last programmed in C. I am using Eclipse, and this is an IDE-related bug. I ran the program through the CMD and output was fine. So it's just something I'll have to deal with for the moment if I want faster console testing through Eclipse. Thanks though! – Chris Cirefice Sep 24 '13 at 00:29
  • Totally agree 'fflush' is not 'elegance'. I would consider it a workaround, given the editor limitation I might even add something along the lines of `#if defined(DEBUG) fflush(stdout) #endif` so that it does not go out in production code. – miltonb Sep 24 '13 at 00:41
1

Sounds like printf is buffering the output on you.

Use fflush(stdout); after the call to printf or add a \n. The newline character basically does the same thing. Or you could even disable buffering all together with setbuf(stdout, NULL);.

Freddie
  • 871
  • 6
  • 10