c语言中的scanf数学表达式

c语言中的scanf数学表达式,c,scanf,C,Scanf,我是c语言学习的初学者,我有一个问题。 我必须编写以下代码:用户输入一个数学表达式,例如2+3*7,代码应发送结果,并考虑*和/的优先级 我想在第一步将用户的表达式输入到一个字符数组中(禁止使用string) int counter=0; char test[50],input; while (counter < 50 && scanf("%c", &input) != EOF ){ test[counter] = input; counter++

我是c语言学习的初学者,我有一个问题。
我必须编写以下代码:用户输入一个数学表达式,例如
2+3*7
,代码应发送结果,并考虑
*
/
的优先级

我想在第一步将用户的表达式输入到一个字符数组中(禁止使用string

int counter=0;
char test[50],input;

while (counter < 50 && scanf("%c", &input) != EOF ){
    test[counter] = input;
    counter++;
}

for (i = 0; i < counter; i++){
    printf("%c ", test[i]);
}
int计数器=0;
字符测试[50],输入;
while(计数器<50&&scanf(“%c”,&input)!=EOF){
测试[计数器]=输入;
计数器++;
}
对于(i=0;i
但是当用户进入时,代码没有退出循环。怎么了?
我的第二个问题是,如果我不能使用string,那么将表达式输入char数组是否是一个好主意?
我可以通过这种方式获得表达式的所有字符吗

但是当用户进入时,代码没有退出循环

您的代码在获得EOF(通常意味着用户按Ctrl+D)或输入了50个字符(而不是按enter键)之前不会退出循环。如果要在用户按enter键时结束,则需要检查最后一个字符输入是否为换行符

此外,如果您一次读取一个字符,则
getchar
可能比scanf更好

只要一次读取的字符数不超过缓冲区的大小,并且确保不会溢出缓冲区,就可以读取字符数组

编辑

有点开玩笑,如果不能使用字符串的要求只是意味着不能使用string.h,并且表达式中不允许使用空格(因此“4+5”有效,但“4+5”无效),您可以这样做:

char test[51],input;
scanf("%50s" &input);
printf("%s", input);
test
中的额外字符用于空终止符

但是当用户进入时,代码没有退出循环

如果希望循环在ENTER键后中断,则必须在您的条件下检查:

while (counter < 50 && scanf("%c", &input) != EOF && input != '\n' ) {
...
}
while(计数器<50&&scanf(“%c”,&input)!=EOF&&input!='\n'){
...
}
我的第二个问题是,输入表达式是否是一个好主意 如果我不能使用字符串,是否将其转换为字符数组


对。很好。C字符串和字符数组(例如终止的NUL字节)之间没有什么区别。因此,如果您不能使用字符串/行读取函数,例如
fgets(str、sizeof str、stdin)
scanf(“%s”,buf),那么您就没有太多的选择。

您基本上需要编写一个。您可以首先使用一些(从字符流中提供一个令牌流)。然后,从令牌流中,解析器要么在内存中构建一个表达式,要么(在没有变量的表达式的简单情况下)在解析过程中计算表达式。任何一本关于编译器的好书(如《汇编》)都会详细解释这一点

有几种工具可以生成解析器和词法分析器。它们被(夸张地)调用(但它们实际上应该被称为解析器生成器)。GNU就是这样一个工具。但是你可以考虑(可能是一些旧版本,或者PCCts)

你想要达到的是一个非常标准的练习。
野牛
的文档中给出了一个;维基页面也有非常相似的代码


关于
scanf
,请阅读&(以及
ungect
…)的文档。您可以使用(或者甚至在终端上)读取整行内容(以便更轻松地进行分析),或者……

您正在测试
scanf()
EOF
,这是对错误或文件结尾的测试,否则
scanf()
将返回与成功转换的格式字符串匹配的字段数。在这种情况下,当输入来自控制台时,它不会失败,因为
%c
将匹配任何字符,
scanf()
将在控制台上无限期等待(如果没有字符存在)-您可以将EOF注入控制台输入,但在这种情况下,这似乎不太可能

这里不需要
scanf()
,更简单的
getchar()
就足够了:

do
{
    input = getchar() ;
    test[counter] = input;
    counter++;

} while( counter < sizeof(test) && input != '\n' ) ;
do
{
input=getchar();
测试[计数器]=输入;
计数器++;
}而(计数器
请注意,与原始代码一样,这并没有添加nul终止符(因此从这个意义上讲,它不是“字符串”)


由于对stdio的哪些部分可能被明显使用的限制有些不合理:

do
{
    scanf( "%c", &input ) ;
    test[counter] = input;
    counter++;

} while( counter < sizeof(test) && input != '\n' ) ;
do
{
scanf(“%c”,&input);
测试[计数器]=输入;
计数器++;
}而(计数器
但是当用户进入时,代码没有退出循环

输入或
“\n”
是一个有效的
char
,可以用
scanf(“%c”,&input)
读取。它的读法与
'2'
'+'
一样简单

我的第二个问题是,如果我不能使用string,那么将表达式输入char数组是否是一个好主意

是的,这是合理的。代码需要1)不存储char超过数组大小2)跟踪数组中使用的元素

我可以通过这种方式获得表达式的所有字符吗

如果您不能使用stings,则可能无法使用
“%c”
。使用
fgetc(),fputc()

#定义N 50
int计数器=0;
炭试验[N];
int输入;//使用int来区分EOF和字符。
而(计数器
注意C本身没有
字符串
数据类型;在C语言中,字符串只是以0值字节(或多字节字符串的字节序列)结尾的字符值序列。字符串存储为
char
数组,但并非每个
char
数组都包含字符串

如果你只是想
#define N 50
int counter=0;
char test[N];
int input;  // use int to distinguish EOF from a character.

while (counter < N && (input = fgetc(stdin)) != '\n' && input != EOF) {
  test[counter] = input;
  counter++;
}

for (i = 0; i < counter; i++){
  fputc(test[i], stdout);
}
char buffer[N]; // where N is large enough for one line's worth of input;
                // let's call it 80 for now.

while ( fgets( buffer, sizeof buffer, stdin ) )
{
  // process buffer
}