2013-09-24 5 views
0

Я знаю, что scanf плохой, и все, но мы не будем тестировать на недопустимый ввод на этом (предположим, что он всегда действителен). Однако, когда я звоню в promptPlayer(), который имеет вызов scanf, вывод на консоль останавливается (что не имеет никакого смысла, потому что все выходные данные должны быть в консоли до, даже звонки на scanf сделаны. координат, разделенных пробелами (как показано на выходе)Scanf in C вызывает поведение Bizarre Console?

Вот код (важное вещество):.

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_engi ne.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; 
} 

Наконец, 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); 

Вот результат: В основном выходной поток не прекращается в течение всей программы, пока после всех scanf s были оценены. Я понятия не имею, что вызывает это.

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 

Это действительно не имеет никакого смысла. Все печатает отлично до тех пор, пока не будет вызван метод promptPlayer - значения принимаются правильно, поэтому я действительно не вижу проблемы ... Кажется, что scanf останавливает вывод консоли (магически?) До тех пор, пока значения не будут введены - тогда он печатает все на консоль все сразу. Я просто знаю, что это действительно очевидно.

+0

На всякий случай; если вы используете Eclipse, этот вопрос SO имеет значение: http://stackoverflow.com/questions/13035075/printf-not-printing-on-console. Поэтому попробуйте запустить скомпилированный exe вне вашего инструмента редактора, поскольку он кажется также проблемой в некоторых других редакторах. – miltonb

+1

Поскольку вы не проверяете возвращаемое значение из 'scanf()' в 'promptPlayer()', вы не знаете, работает оно или нет. Проверь это. Также рассмотрите возможность использования 'fgets()' для чтения строки, а затем 'sscanf()' для ее анализа, вместо того, чтобы полагаться на 'scanf()', который будет радостно принимать несколько входов по одной строке или одному входу по нескольким строкам, что может привести к путанице. –

+0

Джонатан, я подтвердил возвращаемые значения этой функции, напечатав их (отмеченные на выходе). Но это ошибка Eclipse IDE. Программа в целом отлично работает через CMD в Windows, и я помню, как я видел эту ошибку год назад, когда я последний раз программировался на C. Как сказал miltonb, ошибка была отмечена как WONT-FIX, так что это просто что-то, что Eclipse IDE-пользователи с которыми придется иметь дело! –

ответ

3

Я пропустил небольшой код вашего кода promptPlayer, и на мой взгляд, я не вижу ничего, что действительно неправильно с вашим кодом, и он делает то, что ожидается. Я думаю, что это проблема вне вашего кода, который, вероятно, будет использоваться редактором и его взаимодействие с консолью, например, Eclipse или Mintty

Попробуйте запустить скомпилированный exe вне вашего инструмента редактора и выясните, получаете ли вы та же проблема.

Предполагая, что это что-то вроде выше, то, добавив следующий код, чтобы удалить вывод может также решить проблему:

Coordinate desiredLocation; 
    printf("Player %d's turn (enter row and column): ", player); 
    fflush(stdout); 
    scanf("%d %d", &desiredLocation.x, &desiredLocation.y); 
+0

Этот ответ частично разрешил проблему. Я добавил 'fflush (stdout)' в начало и конец функции 'promptPlayer'. Не идеально, но и не то, что я хотел. Оказывается, ваш комментарий к моему вопросу был правдой, и я помню это примерно год назад, когда я последний раз программировал на C. Я использую Eclipse, и это ошибка, связанная с IDE. Я запускал программу через CMD, и выход был прекрасен. Так что это просто то, с чем мне придется столкнуться на данный момент, если я хочу быстрее протестировать консоль через Eclipse. Спасибо хоть! –

+0

Полностью согласен 'fflush' не 'элегантность'. Я считаю это обходным решением, учитывая ограничение редактора, я мог бы даже добавить что-то по строкам '#if defined (DEBUG) fflush (stdout) # endif', чтобы он не вышел в производственном коде. – miltonb

1

Похоже printf буферизация вывода на вас.

Использовать fflush(stdout); по телефону printf или добавить \n. Символ новой строки в основном делает то же самое. Или вы можете даже отключить буферизацию вместе с setbuf(stdout, NULL);.

Смежные вопросы