C - чтение только одного символа с помощью getchar () - PullRequest
0 голосов
/ 23 января 2020

У меня возникли некоторые проблемы с getchar (), в частности, у меня есть char, который через некоторое время l oop возвращает значение, возвращаемое getchar (), но я хочу взять только первый char и, если Я вставляю более длинную строку (например, «aaawssdawa»), мне все еще нужен только первый символ. Вместо этого мой код обрабатывает всю строку.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define ROWS 20
#define COLUMNS 65

char grid[ROWS][COLUMNS];
int score = 0;
void fillGridInitializer();
void printGrid();
void start();
void printScore();
void printAll();
int main(int argc, char *argv[]) {
  start();
  return 0;
}
void start() {
  char movement;
  int riga = 0, colonna = 0;
  fillGridInitializer();
  grid[riga][colonna] = '#';
  system("clear");
  printAll();
  while (1) {
    movement = getchar();
    switch (movement) {
    case 'w':
      if ((riga - 1) >= 0) {
        grid[riga][colonna] = '-';
        riga = riga - 1;
      }
      break;
    case 's':
      if ((riga + 1) < ROWS) {
        grid[riga][colonna] = '-';
        riga = riga + 1;
      }
      break;
    case 'a':
      if ((colonna - 1) >= 0) {
        grid[riga][colonna] = '-';
        colonna = (colonna - 1) % COLUMNS;
      }
      break;
    case 'd':
      if ((colonna + 1) < COLUMNS) {
        grid[riga][colonna] = '-';
        colonna = (colonna + 1) % COLUMNS;
      }
      break;
    default:
      break;
    }
    if (movement == 'p') {
      printf("+++++Game Over+++++\n\n");
      break;
    }
    system("clear");
    grid[riga][colonna] = '#';
    printAll();
  }
}

void printAll() {
  printScore();
  printGrid();
}
void fillGridInitializer() {
  int i = 0, j = 0;
  for (i = 0; i < ROWS; i++) {
    for (j = 0; j < COLUMNS; j++) {
      grid[i][j] = '-';
    }
  }
}
void printScore() { printf("\t SCORE: %d\n", score); }
void printGrid() {
  int i = 0, j = 0;
  for (i = 0; i < ROWS; i++) {
    printf("\t");
    for (j = 0; j < COLUMNS; j++) {
      printf("%c", grid[i][j]);
    }
    printf("\n");
  }
}

Ответы [ 2 ]

1 голос
/ 23 января 2020

После обработки первого символа вызывайте getchar() в al oop, пока не получите символ новой строки или EOF.

Также, getchar() возвращает int, вы должны соответственно объявить переменную, так что вы можете сравнить с EOF правильно.

void start() {
  int movement;
  int riga = 0, colonna = 0;
  fillGridInitializer();
  grid[riga][colonna] = '#';
  system("clear");
  printAll();
  while (1) {
    movement = getchar();
    if (movement == EOF) {
        break;
    }
    switch (movement) {
    case 'w':
      if ((riga - 1) >= 0) {
        grid[riga][colonna] = '-';
        riga = riga - 1;
      }
      break;
    case 's':
      if ((riga + 1) < ROWS) {
        grid[riga][colonna] = '-';
        riga = riga + 1;
      }
      break;
    case 'a':
      if ((colonna - 1) >= 0) {
        grid[riga][colonna] = '-';
        colonna = (colonna - 1) % COLUMNS;
      }
      break;
    case 'd':
      if ((colonna + 1) < COLUMNS) {
        grid[riga][colonna] = '-';
        colonna = (colonna + 1) % COLUMNS;
      }
      break;
    default:
      break;
    }
    if (movement == 'p') {
      printf("+++++Game Over+++++\n\n");
      break;
    }
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF) {} # ignore the rest of the line
    if (ch == EOF) {
        break;
    }
    system("clear");
    grid[riga][colonna] = '#';
    printAll();
  }
}
0 голосов
/ 23 января 2020

Если вы просто хотите прочитать символ и отбросить все остальное в той же строке, вы можете сделать следующее:

Просто прочитать строку и сохранить только первый символ.

Но , вы не должны использовать это, так как оно уязвимо для переполнения буфера (прочитайте, что будет после него).

char read(){
    char buf[BUF_SIZE];
    gets(buf);
    return buf[0];
}

Но вы не должны использовать gets из-за возможных переполнений буфера.

Чтобы предотвратить это, вы можете использовать fgets (см. this ):

char read(){
    char buf[BUF_SIZE];
    fgets(buf,BUF_SIZE,stdin);
    return buf[0];
}

В обоих случаях BUF_SIZE - это константа, определяющая максимальную длину строки. Второй пример защищен от переполнения буфера, но он будет работать только в том случае, если строка заканчивается до окончания буфера. Вы можете просто позвонить fgets несколько раз, чтобы обойти эту проблему:

char read(){
    char buf[BUF_SIZE];
    do{
        fgets(buf, BUF_SIZE,stdin);
    }while(buf[strlen(buf)]!='\n');
    return buf[0];
}

Обратите внимание, что последний метод требует <string.h>.

Интегрирован в ваш код, это будет что-то как это:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#define ROWS 20
#define COLUMNS 65
#define BUF_SIZE 255

char grid[ROWS][COLUMNS];
int score = 0;
void fillGridInitializer();
void printGrid();
void start();
void printScore();
void printAll();
int main(int argc, char *argv[]) {
  start();
  return 0;
}
void start() {
  char movement;
  int riga = 0, colonna = 0;
  fillGridInitializer();
  grid[riga][colonna] = '#';
  system("clear");
  printAll();
  while (1) {
    movement = read();
    switch (movement) {
    case 'w':
      if ((riga - 1) >= 0) {
        grid[riga][colonna] = '-';
        riga = riga - 1;
      }
      break;
    case 's':
      if ((riga + 1) < ROWS) {
        grid[riga][colonna] = '-';
        riga = riga + 1;
      }
      break;
    case 'a':
      if ((colonna - 1) >= 0) {
        grid[riga][colonna] = '-';
        colonna = (colonna - 1) % COLUMNS;
      }
      break;
    case 'd':
      if ((colonna + 1) < COLUMNS) {
        grid[riga][colonna] = '-';
        colonna = (colonna + 1) % COLUMNS;
      }
      break;
    default:
      break;
    }
    if (movement == 'p') {
      printf("+++++Game Over+++++\n\n");
      break;
    }
    system("clear");
    grid[riga][colonna] = '#';
    printAll();
  }
}

void printAll() {
  printScore();
  printGrid();
}
void fillGridInitializer() {
  int i = 0, j = 0;
  for (i = 0; i < ROWS; i++) {
    for (j = 0; j < COLUMNS; j++) {
      grid[i][j] = '-';
    }
  }
}
void printScore() { printf("\t SCORE: %d\n", score); }
void printGrid() {
  int i = 0, j = 0;
  for (i = 0; i < ROWS; i++) {
    printf("\t");
    for (j = 0; j < COLUMNS; j++) {
      printf("%c", grid[i][j]);
    }
    printf("\n");
  }
}
char read(){
    char buf[BUF_SIZE];
    do{
        fgets(buf, BUF_SIZE,stdin);
    }while(buf[strlen(buf)]!='\n');
    return buf[0];
}
...