C - 使用 getchar() 只读取一个字符
C - Reading just one character with getchar()
我在使用 getchar() 时遇到了一些问题,特别是我有一个 char,它在 while 循环中获取从 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");
}
}
处理完第一个字符后,循环调用 getchar()
,直到得到换行符或 EOF。
此外,getchar()
returns 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();
}
}
假设您只想读取一个字符并丢弃同一行中的所有其他内容,您可以执行以下操作:
只读一行,只保存第一个字符。
但是,你不应该使用它,因为它容易受到缓冲区溢出的影响(阅读它后面的内容)。
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];
}
我在使用 getchar() 时遇到了一些问题,特别是我有一个 char,它在 while 循环中获取从 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");
}
}
处理完第一个字符后,循环调用 getchar()
,直到得到换行符或 EOF。
此外,getchar()
returns 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();
}
}
假设您只想读取一个字符并丢弃同一行中的所有其他内容,您可以执行以下操作:
只读一行,只保存第一个字符。
但是,你不应该使用它,因为它容易受到缓冲区溢出的影响(阅读它后面的内容)。
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];
}