C语言如何持续输入double直到EOF并计算平方根(不使用<math.h>)
解决方案
核心实现逻辑
C语言的标准输入函数遇到EOF(输入结束符)时会返回固定标识,我们可以通过判断返回值控制循环终止:
- 用
scanf读取数值时,返回值为成功读取的变量个数,返回EOF(值为-1)时说明读取到输入结束符 - 用
fgets读取整行字符串时,返回NULL说明读取到EOF
以下提供两种适配你现有代码的修改方案,默认先一次性输入固定精度,之后循环读取待计算的数值直到EOF:
方案1:直接用scanf读取double值
无需改动你已实现的工具函数,仅修改main函数即可,适配你原有调用逻辑:
#include <stdio.h> double todouble(char *a) { double ans=0; while(*a!='.' && *a!='\0') { for(int i=48; i<58; i++) { if(*a==i) { ans=ans*10+(i-48); break; } } a++; } if(*a=='\0') { return ans; } else if(*(a+1)=='\0') { return ans; } a++; double temp=1; int count=1; do { for(int i=48; i<58; i++) { if(*a==i) { for(int j=0; j<count; j++) { temp=temp/10; } temp*=(i-48); ans+=temp; temp=1; count++; break; } } a++; } while(*a!='\0'); return ans; } double myabs(double a, double b) { if(a>b) { return (a-b); } else { return (b-a); } } double squareroot(double pr, double x) { // 新增边界判断,优化特殊值计算效率 if (x == 0) return 0; double a=1; double b=(x+1)/2; double dif=myabs(a,b); while(dif>=pr) { a=b; b=(a+(x/a))/2; dif=myabs(a,b); } return b; } int main() { double eps, x; printf("Please type in the value of Epsilon: "); // 先读取精度,读取失败直接退出 if (scanf("%lf", &eps) != 1) { printf("Invalid epsilon input\n"); return 1; } printf("Please input numbers to calculate square root:\n"); printf("Windows: press Ctrl+Z then Enter to exit | Linux/macOS: press Ctrl+D to exit\n"); // 循环读取x,直到遇到EOF while (scanf("%lf", &x) == 1) { if (x < 0) { printf("%.10g is negative, square root is not a real number\n", x); continue; } double ans = squareroot(eps, x); printf("sqrt(%.10g) = %.10g\n", x, ans); } printf("\nEnd of input, program exit\n"); return 0; }
方案2:使用自定义todouble函数转换输入
如果你希望调用自己实现的字符串转double功能,可以修改循环逻辑为逐行读取字符串再转换,仅需替换main函数代码:
int main() { double eps, x; char buf[1024]; printf("Please type in the value of Epsilon: "); if (!fgets(buf, sizeof(buf), stdin)) { printf("Invalid epsilon input\n"); return 1; } // 去掉换行符后转double char *p = buf; while (*p && *p != '\n') p++; *p = '\0'; eps = todouble(buf); printf("Please input numbers to calculate square root:\n"); printf("Windows: press Ctrl+Z then Enter to exit | Linux/macOS: press Ctrl+D to exit\n"); while (fgets(buf, sizeof(buf), stdin) != NULL) { p = buf; while (*p && *p != '\n') p++; *p = '\0'; x = todouble(buf); if (x < 0) { printf("%.10g is negative, square root is not a real number\n", x); continue; } double ans = squareroot(eps, x); printf("sqrt(%.10g) = %.10g\n", x, ans); } printf("\nEnd of input, program exit\n"); return 0; }
注意:你当前的
todouble函数暂不支持负数字符串转换,如果需要处理负数输入可以补充对'-'开头的字符串的判断逻辑。
内容的提问来源于stack exchange,提问作者Delev1n
相关产品推荐
相关产品推荐

