C-读取大于接受值的输入时在标准DIN中清除故障

C-读取大于接受值的输入时在标准DIN中清除故障,c,parsing,stdin,C,Parsing,Stdin,我正在编写交互式数独游戏,并从控制台解析命令 我想将用户命令限制为最多256个字符,而任何额外的字符都将打印错误消息,并通知他它超过了最大长度 所以我为256长度的字符数组分配了内存,并通过fgets函数读取这个输入,然后将它传递给解析器函数,这是我这部分的代码- 注意输入是我从fgets func传递的输入 Command parseCommand(char *input, int upperBound, MODE* mode){ Command command; char* token;

我正在编写交互式数独游戏,并从控制台解析命令

我想将用户命令限制为最多256个字符,而任何额外的字符都将打印错误消息,并通知他它超过了最大长度

所以我为256长度的字符数组分配了内存,并通过fgets函数读取这个输入,然后将它传递给解析器函数,这是我这部分的代码- 注意输入是我从fgets func传递的输入

Command parseCommand(char *input, int upperBound, MODE* mode){

Command command;
char* token;
char *copyInput = (char*) malloc(strlen(input)*sizeof(char));

if(copyInput == NULL){
    printf("Error: parseCommand has failed\n");
    free(copyInput);
    exit(EXIT_FAILURE);
}

command.cmd = ERROR;
strcpy(copyInput,input);
token = strtok(input,delim);

if(strlen(copyInput) > 256){
    command.cmd = MAX_ARGS_REACHED;
    clear();
}...//More code following to that but irrelvant
现在我相信问题出在我的clear函数中,因为那里没有发生任何事情,它也不会离开它,但是如果我按enter twich,那么它是258个字符,它工作得很好,例如,每一个大于257的输入都工作得很好,只有257有问题

void clear(){
int c = 0;
while ((c = getchar()) != '\n' && c != EOF) { }
}

希望能在这里得到帮助,谢谢

编辑-以下代码显示我如何读取输入并将其传递给上述函数-

void runGame(){
Game* game;
char* input = (char*) malloc(256 * sizeof(char));
if(input == NULL){
    printf("Error: Program has failed!\n");
    free(input);
    exit(EXIT_FAILURE);
}

printf("Welcome to Sudoku Game!\n");
game = createGame();

while(1){

    Command command;
    printf("Please enter a Command\n");
    if(!fgets(input,ARRSIZE,stdin)){/*checks if reading user input failed or EOF*/
        exitCommand(game);
        free(input);
        return;
    }

    command = parseCommand(input,game->rows,&game->mode);//More code following to that
至少是这个问题

内存分配不足

空字符需要+1。(C中不需要强制转换)


输入数组大小不足

我想将用户命令限制为最多256个字符
ARRSIZE=256

除此之外,我认为这是OP的关键问题,读取一行输入需要一个更大的数组

strlen(copyinport)>256
对于
fgets(input,256,stdin)
永远不会为真。缓冲区
输入
的字符串长度最多为255

不清楚OP是否考虑输入的Enter或
'\n'
部分<代码>fgets()可以

trip
strlen(copyInput)>256需要长度至少为257的字符串

要读取最多257行(不计算潜在的
'\n'
),代码应使用256+1+1+1长度的缓冲区

#define CMD_N 256
//                      extra to test too long, \n, \0  
#define BUFFER_N (CMD_N + 1                    + 1 + 1)


char* input = malloc(BUFFER_N);
....
if(!fgets(input,BUFFER_N,stdin)) {
  buffer[strcspn(buffer, "\n")] = '\0';  // lop off potential \n
  ....

if(strlen(copyInput) > CMD_N) {
建议:

在调用
fgets()
之后执行以下操作:

int ch;
while( (ch = getchar()) != EOF && ch != '\n' ){;}

由于这将正确地消耗
stdin

中的任何剩余数据,您未能显示如何获得
输入,我假设您使用clear与此不一致。无论如何,您不应该混合使用直接io和缓冲区处理。由于
parseCommand
是一个缓冲区处理程序,它不应该直接或间接地使用
getchar
,而让执行io的调用方使用它。这样,可能出现的问题就更容易发现。@user3121023如果您更正,但如果输入大于257,我仍然需要清理stdin,否则它将保留在那里,下次用户输入命令时,它将获得之前未读取的输入…我可以用另一个if\else解决它,但我认为有一个简洁的解决方案。我已经添加了显示如何读取输入的相关代码。@user3121023无法编辑。对于257以上的字符,它不能正常工作,因为我的缓冲区中仍然有剩余的字符,下面的用户输入包括257以上的先前字符…编辑的代码缺少重要信息。我无法编译它/什么是
ARRSIZE
?例如发布一个@chux,ARRSIZE=256,我将遵循此指南,谢谢。@omrib40
input
是一个。谢谢,最终我想我找到了另一种方法,我只是检查了输入的最后一个字符是否为'\n',如果是,那么它没有超过限制,否则就是。非常感谢您的评论,谢谢。
int ch;
while( (ch = getchar()) != EOF && ch != '\n' ){;}