[英]How NOT to read float type in scanf when reading type int
我需要將兩個整數(僅此而已)寫入變量。 它進行驗證以確保所有 args 都不是字符串並且它們不是空的並且除了被零除,或者當我將 float 作為第一個 arg 但當我將 float 作為第二個參數時它不會產生異常。 如何僅使用stdio.h
解決它?
#include <stdio.h>
void sum(int a, int b);
void dif(int a, int b);
void prod(int a, int b);
void qut(int a, int b);
int main() {
int x, z;
int digits = scanf("%d %d", &x, &z);
if (digits != 2) {
printf("n/a\n");
return 2;
}
else {
sum(x, z);
dif(x, z);
prod(x, z);
qut(x, z);
}
return 0;
}
void sum(int a, int b) {
printf("%d ", a + b);
}
void dif(int a, int b) {
printf("%d ", a - b);
}
void prod(int a, int b) {
printf("%d ", a * b);
}
void qut(int a, int b) {
if (a == 0 || b == 0) {
printf("n/a\n");
}
else {
printf("%d\n", a / b);
}
}
抱歉,我知道代碼很簡單,我的問題很愚蠢:) 謝謝!
正如評論中提到的, scanf
是這項工作的錯誤工具。 scanf
在錯誤處理方面是出了名的糟糕。
從理論上講,使用scanf
解決這個問題是可能的——幾乎不可能。 出於同樣的原因,可以使用錘子將螺釘擰入一塊木頭。 但這是一個可怕的想法。 一位教他的學生用錘子打螺絲的木匠老師會因為不稱職而被解雇。 但出於某種原因,我們容忍了初學編程教師的這種無能。
通常我不在這里做作業問題; 通常這也是個壞主意; 通常,讓學生做作業並獲得學習會更有意義。 但是,對於像這樣的愚蠢作業,我毫不猶豫地為您提供一個完整的解決方案,因此您可以擺脫不稱職的教練,繼續學習更有用的東西。 這是基本思想:
fgets
讀取一行文本(整行)。sscanf
解析該行,確保它包含一個數字和一個數字,僅此而已。%d
讀取第一個整數,使用 % %d
讀取第二個整數,然后我們將使用第三個%c
來讀取接下來出現的任何字符。 如果該字符不是標記行尾的\n
之外的任何字符,則表明用戶輸入了錯誤的內容,例如字符串或.
這是浮點數的一部分。這與user3121023的解決方案基本相同。
int main()
{
char line[100];
int x, z;
char dummy;
if(fgets(line, sizeof(line), stdin) == NULL) return 1;
int digits = sscanf(line, "%d%d%c", &x, &z, &dummy);
if(digits < 2 || digits > 2 && dummy != '\n') {
printf("n/a\n");
return 2;
}
...
腳注:這里的代碼有一個不幸的小故障:如果用戶在第二個數字之后但在換行符之前鍵入一個空格,代碼將拒絕它n/a
。 有一些方法可以解決這個問題,但在我看來,對於這個練習,它們是不值得的; 它們屬於“收益遞減規律”。 如果您的用戶抱怨,就像到處都是不可救葯的軟件供應商:提醒他們應該輸入兩個數字而不是其他數字,而他們在第二個數字之后輸入的空格是“其他”,所以這是他們的錯,而不是您的錯漏洞。 :-)
掃描完整數后,使用循環掃描一個空白字符。 在換行符上跳出循環。
對於任何其他字符,掃描將返回0
。
#include <stdio.h>
void sum(int a, int b);
void dif(int a, int b);
void prod(int a, int b);
void qut(int a, int b);
int main() {
char ws[2] = ""; // whitespace
int scanned = 0;
int x, z;
int digits = scanf("%d %d", &x, &z);
if (digits != 2) {
printf("n/a\n");
return 2;
}
while ( ( scanned = scanf( "%1[ \t\n]", ws))) { // scan for 1 whitespace
if ( scanned == EOF) {
fprintf ( stderr, "EOF\n");
return 1;
}
if ( ws[0] == '\n') {
break;
}
}
if ( scanned != 1 || ws[0] != '\n') {
printf("n/a\n");
return 3;
}
else {
sum(x, z);
dif(x, z);
prod(x, z);
qut(x, z);
}
return 0;
}
void sum(int a, int b) {
printf("%d ", a + b);
}
void dif(int a, int b) {
printf("%d ", a - b);
}
void prod(int a, int b) {
printf("%d ", a * b);
}
void qut(int a, int b) {
if (a == 0 || b == 0) {
printf("n/a\n");
}
else {
printf("%d\n", a / b);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.