c - 为什么我在输入字母字符时得到 0.00?
问题描述
以下是我编写的代码。我觉得我错过了指针的某些内容,或者可能在计算中出错了。但就我所见,一切对我来说似乎都很好,但是当我输入时,例如:你好或其他任何东西,它会给我 0.00 作为输出。
下面是正确的
Enter a number:
6
Your number is: 6.00
但这为什么呢?
Enter a number:
h
Your number is: 0.00
以下是完整代码:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 250
float myAtof(char *string, char *error);
int main() {
char string[SIZE]; // Array declaration.
float fnum1;
char errorState=0;
printf("Enter a number:\n");
gets(string);
fnum1=myAtof(string,&errorState);
if (errorState == 0) {
printf("Your number is: %.2f \n", fnum1);
} else if (errorState == 1) {
printf("Error has been occurred due to inappropriate input!\n");
}
return 0;
}
float myAtof(char* string, char* error) {
*error != '1';
float num= 0;
float decimalFlag = 1;
int decimalNumberFound = 0;
for (int i = 0; string[i]!= '\0'; i++) {
char ch = string[i];
if (ch != '.' && (ch < '0' || ch >'9')) {
error ='1';
return 0;
}
if (decimalNumberFound == 1 && ch == '.') {
error = '1';
return 0;
} else {
num = num* 10 + (ch - '0');
if (decimalNumberFound == 1)
decimalFlag *= 10;
}
}
num = num / decimalFlag;
return num;
}
解决方案
由于您的myAtof
例程有一个用于报告错误的参数,并且您的main
例程测试了错误报告变量 ,errorState
因此您可能希望程序在您输入“h”或其他非数字时打印一条错误消息,而您的问题是它为什么打印“0.00”而不是错误消息。
在用 声明的函数中float myAtof(char* string, char* error)
,error
是一个指针,*error
是它所指向的东西。因此,当代码执行时error = '1';
,它会尝试将指针设置为'1'
. 它不会改变它指向的东西。
当你编译这个时,编译器会发出一条警告消息,比如“警告:不兼容的整数到指针转换分配给 'char *' from 'int'”。您不应该忽略该消息。
该函数还包含语句*error != '1';
。该声明没有任何作用。它说要比较 to 的值,*error
看看'1'
它们是否不相等。运算符的结果!=
是 1 或 0,表示值是否不相等。但该声明与该结果无关。它只是被丢弃,因此该语句无效。
函数中的任何内容都不会改变 的值*error
,因此它指向的东西errorState
inmain
永远不会改变。所以main
没有看到发生了错误。它评估errorState==0
为 true 并执行printf("Your number is: %.2f \n", fnum1);
。
要解决此问题,请删除该语句*error != '1';
并将两个error = '1';
语句更改为*error = '1';
.
此外,更改'1'
为1
. 设置*error
为'1'
将其设置为字符“1”的代码。它不会将其设置为值 1,这是errorState == 1
测试的内容。通常,错误状态是 0 或 1,而不是 0 或'1'
。
也else if (errorState == 1)
改为else
. 当您有一个if
andelse
旨在在某个条件X及其替代条件之间进行完全选择时,您不需要第二次测试。使用您的代码,如果 X 为真,则执行第一个,如果X 为假且 Y 为真,则执行第二个,如果X 为假且Y为假,则两者均不执行。但绝不应该出现X为假而Y为假的情况——您希望程序始终要么有一个数字,要么有一个错误状态。应该只有两种可能,而不是三种。所以只用if (X) { … } else if (Y) { … }
{ … }
{ … }
else
,不是else if
。
errorState
(从概念上讲,如果程序有0 或 1 以外的值,这是一个错误,因此如果程序正常工作,它永远不会同时出现X false 和Yelse if
false ,这没关系。但你确实有一个错误,这不会导致两者都不会{ … }
被执行。将代码设计为使用else
而不是不必要的代码else if
使其在出现错误时更能抵抗行为不端。以这种方式设计稳健的程序很有用。)
还要注意来自编译器的警告消息。最好告诉编译器将所有警告视为错误,这样您的程序将不会在警告消息仍然存在时编译。如果您使用的是 GCC 或 Clang,请使用该-Werror
开关。如果您使用的是 Microsoft Visual C++,请使用/WX
.
推荐阅读
- windows - git-bash 生成默认的 .bashrc
- asp.net - 会话变量在来自另一个提供者的回调中丢失
- php - 点击提交按钮没有响应
- r - 使用两个向量循环代码以使用 R 生成一个 xlsx 输出
- php - 警告:session_start():无法发送会话缓存限制器 - 标头已发送。请建议
- azure - Azure 自动化:Runbook、RunAs 帐户:如何允许访问 AAD(例如 Get-AzADUser)?
- spring-boot - 如果上一个作业仍在运行,如何防止在 Spring Batch 上执行计划作业?
- javascript - 未捕获的 ReferenceError:初始化时未在 onload 定义
- php - PHP合并多个数组比较3个键和值
- c# - 如何使用 HttpClient 发送大于 ~28MB 的文件