无论我选择什么选项,我总是会提示输入一个新的移位值(好像我输入1作为我的选择)。为什么这段代码会忽略我选择的选项?
#include <stdio.h>
#include <string.h>
#define SIZE 500
int getUserChoice()
{
int decision = 0;
printf("-------------------------------\n");
printf("| 1) Change Shift (default 3) |\n");
printf("| 2) Encrypt a message |\n");
printf("| 3) Decrypt a message |\n");
printf("| 4) Quit |\n");
printf("-------------------------------\n");
printf("Option: ");
scanf("%d", &decision);
if(decision == 0 || decision >= 4)
{
return 0;
}
return decision;
}
int getShift()
{
int key = 3;
printf("Enter new shift value: ");
scanf("%d", &key);
return 0;
}
void getString(char buf[])
{
int act;
act = SIZE - 1;
int count[26] = {0};
fgets(buf, act, stdin);
return;
}
void encrypt(char buf[], int shift)
{
int i = 0;
for(i = 0; i < strlen(buf);++i)
{
buf[i] = buf[i] + shift;
}
return;
}
void decrypt(char buf[], int shift)
{
int i = 0;
for(i = 0; i < strlen(buf); ++i)
{
buf[i] = buf[i] - shift;
}
return;
}
int main()
{
char userStr[SIZE];
int number = 0;
getUserChoice();
int shift = 0;
if(number = 1)
{
getShift();
}
if (number = 2)
{
getString(userStr);
encrypt(userStr, shift);
}
if (number = 3)
{
getString(userStr);
decrypt(userStr, shift);
}
return 0;
}
答案 0 :(得分:1)
这看起来很像家庭作业,你似乎没有花很多精力去寻找问题,但是我们走了......代码上有几个缺陷:
您的某些函数getUserChoice
和getShift
应该返回一个值,但这些值在代码中完全被忽略。您没有将它分配给任何局部变量,并且它们不会修改其范围之外的任何内容,因此返回的任何值都会丢失。
代码:
if(number = 1){
getShift();
}
应该是:
if(number == 1){
shift = getShift();
}
这让我有了另一个大错误,当C无意中发生时,很多人头疼的原因是:
赋值运算符返回一个值:赋值后的左操作数值。因此表达式if(number = 1)
是有效的,并且每次都会计算为true,因为赋值的返回值始终为1. if(number == 1)
但是,只有当number
等于时才会求值为true 1.我觉得进行比较&#34; Yoda-Style&#34;,像if(1 == number)
这样可以避免那些错误(很容易发生在错字上)。它们很难跟踪,因为代码是有效的,但行为不是预期的。使用&#34; Yoda-Style&#34;比较,如果您输入错误if(1 = number)
,则会出现编译错误,因为这是一项无效的分配。
在函数getUserChoice
上,您有以下条件语句来检查输入是否有效(当无效时,它默认为&#34;退出&#34;选项):
if(decision == 0 || decision >= 4)
{
return 0;
}
但是,由于决策是signed int
,因此负值有效。你没有考虑到这些。以下内容涉及:
if(decision <= 0 || decision >= 4)
{
return 0;
}
getShift
不返回班次值:您在scanf
函数上使用getShift
来获取移位值,但返回0.您应该返回key
值。
getString
上的未使用变量+ fgets
上错误的大小参数:你在getString
上声明了一个0到0的数组,它没有任何用处。另外,来自fgets
手册页:
fgets()从流和中读取最多一个小于字符的字符 将它们存储到s指向的缓冲区中。读后停止了 EOF或换行符。如果读取换行符,则将其存储到缓冲区中。 终止空字节(&#39; \ 0&#39;)存储在最后一个字符之后 缓冲区。
所以你真的不需要从SIZE中减去1,因为它已经考虑了空字符。
stdin
之前不清除fgets
:致电scanf("%d",...);
后,您的stdin
中会有一个挂起的换行符。这是因为解析为scanf
的格式字符串只指示它读取任意数量的十进制数字,不包括跟随它们的换行符。
挂起的换行符会导致您的fgets
在获得任何用户输入之前退出。您需要通过阅读之前stdin
来电中的悬挂字符来清除scanf
。在这个例子中,这是由这个循环完成的:
int c;
while((c = getchar()) != '\n' && c != EOF){
//Clearing Stdin
}
另一种方法是使用:
scanf("%*[^\n]"); scanf("%*c"); //Consume all characters up to \n (if present) then consume exactly one char ('\n' itself)
您只需提示用户一次,执行询问并退出,而不是在他要求退出之前反复询问用户选项。
return
返回函数结束时不必要的void
语句: void
返回函数将在它们结束时返回,因此除非您在函数体结束之前返回,否则无需添加return
语句。
编辑以下代码以解决上述问题:
#include <stdio.h>
#include <string.h>
#define SIZE 500
int getUserChoice()
{
int decision = 0;
printf("-------------------------------\n");
printf("| 1) Change Shift (default 3) |\n");
printf("| 2) Encrypt a message |\n");
printf("| 3) Decrypt a message |\n");
printf("| 4) Quit |\n");
printf("-------------------------------\n");
printf("Option: ");
scanf("%d", &decision);
int c;
while((c = getchar()) != '\n' && c != EOF){
//Clearing Stdin
}
if(decision <= 0 || decision >= 4)
{
return 0;
}
return decision;
}
int getShift()
{
int key = 3;
printf("Enter new shift value: ");
scanf("%d", &key);
int c;
while((c = getchar()) != '\n' && c != EOF){
//Clearing Stdin
}
return key;
}
void getString(char *buf)
{
fgets(buf, SIZE, stdin);
return;
}
void encrypt(char *buf, int shift)
{
int i = 0;
for(i = 0; i <= (strlen(buf)-1);++i)
{
buf[i] = buf[i] + shift;
}
return;
}
void decrypt(char *buf, int shift)
{
int i = 0;
for(i = 0; i <= (strlen(buf)-1); ++i)
{
buf[i] = buf[i] - shift;
}
return;
}
int main()
{
char userStr[SIZE];
int shift = 3;
while(1){
int number = getUserChoice();
if(number == 1)
{
shift = getShift();
}
if (number == 2)
{
getString(userStr);
printf("Message: %s\n", userStr);
encrypt(userStr, shift);
printf("Shifted Message: %s\n", userStr);
}
if (number == 3)
{
getString(userStr);
printf("Shifted Message: %s\n", userStr);
decrypt(userStr, shift);
printf("Message: %s\n", userStr);
}
if (number == 0){
break;
}
}
return 0;
}
答案 1 :(得分:0)
代码中的两件事导致它忽略用户输入。
首先,getUserChoice
函数返回一个值,但main
不存储或使用返回值。函数调用应如下所示:
number = getUserChoice();
其次,单个等号if(number = 1)
充当任务。它将number
设置为值1
。要将number
与1
进行比较,请使用相等运算符,例如
if ( number == 1 )
请注意,当您错误地将赋值放在if
语句中时,任何体面的编译器都会生成警告。您应确保启用所有警告(使用带有gcc或clang的-Wall
,使用带有Microsoft的/W4
),并修复所有警告。如果忽略编译器警告,那么你将无处可去。
您的代码中还有其他问题,但这些问题导致用户输入被忽略。