而循环重复,扫描等于读取的字符数



我有一个程序,旨在获取命令第一个问题是命令将通过键入 c 或 f 在命令行或文件中采用的格式 如果两者都未键入,则 while 循环将重复,而不允许输入等于错误输入中的字符数,而不是停止并允许 scanf 再次抓取输入。我在任何时候都不使用它的返回值,所以我不知道为什么会发生这种情况。正确输入"F"或"C"不会导致问题。 任何帮助将不胜感激

#include<stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define true 1
#define false 0
typedef int bool;
double **temp_array;
double temp1d_array[36];
char consolep[100];
char *fp1;
FILE *fp;
char string_IO1[50];
char string_temp[50];
char buffer[50];
char current_command[10];
int halt = 0;
char *strtodptr;
void main(){
printf("welcome n");
char IO;
char read[250];
char file_console;
int IO_method = 0;
char command[10];
char type_IO;
char type_of_var_IO;
char dim_IO[3];
char array_string_IO[40];
//console or file
//decide IO Method loop 1
while (IO_method==0)
{
printf("please type 'c'for console or 'f' for file to select input typen");
scanf("%c", &file_console);
//if console
if(file_console =='c')
{
IO_method=1;
printf("method is consolen");
}
//if file
else if(file_console=='f')
{
IO_method=2;
printf("method is filen");
printf("please enter a file directoryn");
scanf("%s",&string_IO1);
}
else
{
printf("invalid entryn");  
file_console=NULL;
IO_method=0;
}
}}//code here continues but i compiled it without and has no bearing on the error.

在发布的代码中调用scanf()会在输入流中留下字符。例如,如果用户在第一个提示符下输入g,然后按Enter,则留下n字符。如果用户输入多个字符,则会留下多余的字符。以后对 I/O 函数的调用将选取这些意外字符,从而导致程序行为异常。

一种解决方案是在此类 I/O 函数调用后编写一个小函数来清除输入流:

void clear_input(void)
{
int c;
while ((c = getchar()) != 'n' && c != EOF) {
continue;
}
}

此函数丢弃输入流中保留的任何字符(最多(包括第一个换行符(。请注意,c必须是int,以确保正确处理EOF。另请注意,仅当输入流不为空时,才应调用此函数;空输入流将导致调用 togetchar()阻塞,等待输入。

例如,在第一次调用scanf()之后,您知道输入流中至少还有一个n字符(换行符前面可能有更多字符(;只需调用clear_input()即可在下一次 I/O 调用之前清理输入流:

scanf("%c", &file_console);
clear_input();

scanf()返回的值应该在健壮的代码中检查;返回成功赋值的次数,或者在极少数情况下EOF错误。这有助于验证输入。

更好的选择是使用fgets()stdin读取并将一行输入提取到缓冲区,然后使用sscanf()来分析缓冲区。这里的一个优点是,fgets()将读取所有字符,包括换行符,前提是缓冲区中有足够的空间。因此,分配一个慷慨的buffer[],以使缓冲区中可能包含任何合理的输入。如果需要更加小心,可以检查输入缓冲区中是否有n字符(例如,使用strchr()(。如果在缓冲区中找到n字符,则输入流为空,否则会留下额外的字符,可以调用clear_input()函数来清理内容:

#include <stdlib.h>
#include <string.h>
...
char buffer[1000];
char end;
while (IO_method==0)
{
printf("please type 'c'for console or 'f' for file to select input typen");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
/* Handle input error */
perror("Error in fgets()");
exit(EXIT_FAILURE);
}
/* May need to clear input stream, if input is too large */
if (strchr(buffer, 'n') == NULL) {
clear_input();
}
/* Input again if input is not as expected */
if (sscanf(buffer, "%c%c", &file_console, &end) != 2 || end != 'n') {
continue;
}
...

在这里,buffer[]以较大的大小声明,以容纳所有合理的输入。fgets()将输入放在buffer,直到并包括换行符(空间允许(。请注意,检查来自fgets()的返回值;如果出现罕见的 I/O 错误,则返回空指针。接下来,strchr()用于检查buffer中的n;它应该存在,但如果不存在,则返回一个 null 指针,指示输入流中仍有字符需要清除。接下来,sscanf()用于分析缓冲区。在这里,请注意,end用于将字符存储在用户输入字符之后。在预期输入中,这是一个n字符。如果用户输入的字符过多,测试end将显示此情况,并再次进行输入。

另请注意,在发布的代码中,没有声明string_IO1(而且不是一个很好的名称,因为IO1中的字符很难在屏幕上区分(;如果这是一个字符数组,那么对scanf()的调用应该如下所示:

scanf("%s",string_IO1);

而且,file_console已被声明为char,因此file_console = NULL;是错误的,因为NULL是空指针宏,而不是整数类型。

最新更新