第八章 字符输入/输出和输入验证

  • 程序清单8.1,echo.c:

/* echo.c -- 重复输入 */ 
#include <stdio.h>

int main(void)
{
    char ch;
    
    while ((ch = getchar()) != '#')
        putchar(ch);
        
    return 0;
} 

输出结果:

  • 程序清单8.2,echo_eof.c:

/* echo_eof.c -- 重复输入,直到文件结束 */ 
#include <stdio.h>

int main(void)
{
    int ch;
    
    while ((ch = getchar()) != EOF)
        putchar(ch);
        
    return 0;
} 

输出结果:

  • 程序清单8.3,file_eof.c:

// file_eof.c -- 打开一个文件并显示该文件 
#include <stdio.h>
#include <stdlib.h>                // 提供 exit() 函数原型
 
int main(void)
{
    int ch;
    FILE * fp;
    char fname[50];               // 存储文件名 
    
    printf("Enter the name file: ");
    scanf("%s", fname);
    fp = fopen(fname, "r");       // 打开待读取文件(只读) 
    if (fp == NULL)               // 如果打开失败 
    {
        printf("Failed to open file. Bye\n");
        exit(1);                  // 退出程序 
    }
    while ((ch = getc(fp)) != EOF)
        putchar(ch);
    fclose(fp);                   // 关闭文件 
    
    return 0;
}

打开的文件,a.txt:

adasf

输出结果:

  • 程序清单8.4,guess.c:

/* guess.c -- 一个拖沓且错误的猜数字程序 */ 
#include <stdio.h>

int main(void)
{
    int guess = 1;
    char response;
    
    printf("Pick an integer from 1 to 100. I will try to guess ");
    printf("it.\n Responde with a y if my guess is right and with");
    printf("\nan n if it is wrong.\n");
    printf("Uh...is your number %d?\n", guess);
    while ((response = getchar()) != 'y')
    {
        if (response == 'n')
            printf("Well, then, is it %d?\n", ++guess);
        else
            printf("Sorry, I understand only y or n.\n");
        while (getchar() != '\n')
            continue;    
    }
    printf("I know I could do it!\n");
    
    return 0;
}

输出结果:

  • 程序清单8.6(更正版本的8.5),showchar1.c:

/* showchar1.c -- 有较大I/O 问题的程序 */ 
#include <stdio.h>

void display(char cr, int lines, int width);

int main(void)
{
    int ch;                   // 待打印字符 
    int rows, cols;           // 行数和列数 
    
    printf("Enter a character and two integers:\n");
    while ((ch = getchar()) != '\n')
    {
        if (scanf("%d %d", &rows, &cols) != 2)
            break;
        display(ch, rows, cols);
        while (getchar() != '\n')
            continue;
        printf("Enter another character and two integers: \n");
        printf("Enter a newline to quit.\n");
    }
    printf("Bye.\n");
    
    return 0;
}

void display(char cr, int lines, int width)
{
    int row, col;
    
    for (row = 1; row <= lines; row++)
    {
        for (col = 1; col <= width; col++)
            putchar(cr);
        putchar('\n');          // 结束一行并开始新的一行 
    }
}

输出结果:

  • 程序清单8.7,checking.c:

//checking.c -- 输入验证 
#include <stdio.h>
#include <stdbool.h>

//验证输入是一个整数
long get_long(void);
//验证范围的上下限是否有效
bool bad_limits(long begin, long end,
                long low, long high);
//计算a~b之间的整数平方和
double sum_squares(long a, long b);

int main(void)
{
    const long MIN = -10000000L;    //范围的下限 
    const long MAX = +10000000L;    //范围的上限 
    long start;                        //用户指定的范围最小值
    long stop;                        //用户指定的范围最大值
    double answer;
    
    printf("This program computes the sum of the squares of "
           "integers in a range.\nThe lower bound should not "
           "be less than -10000000 and\n the npper bound "
           "should not be more than +10000000.\nEnter the "
           "limits (enter 0 for both limits to quit):\n"
           "lower limit: ");
    start = get_long();
    printf("upper limit: ");
    stop = get_long();
    while (start != 0 || stop != 0)
    {
        if (bad_limits(start, stop, MIN, MAX))
            printf("Please try again.\n");
        else
        {
            answer = sum_squares(start, stop);
            printf("The sum of the squares of the integers ");
            printf("from %ld to %ld id %g\n",
                    start, stop, answer);
        }
        printf("Enter the limits (enter 0 for both "
               "limits to quit):\n");
        printf("lower limit: ");
        start = get_long();
        printf("upper limit: ");
        stop = get_long();
    }
    printf("Done.\n");
    
    return 0;
}
 
long get_long(void)
{
    long input;
    char ch;
    
    while (scanf("%ld", &input) != 1)
    {
        while ((ch = getchar()) != '\n')
            putchar(ch);
        printf(" is not an integer.\nPlease enter an ");
        printf("integer value, such as 25, -178, or 3: ");
    }
     
    return input;
}
 
double sum_squares(long a, long b)
{
    double total = 0;
    long i;
    
    for (i = a; i <= b; i++)
        total += (double) i * (double) i;
        
    return total;
}
 
bool bad_limits(long begin, long end,
     long low, long high)
{
    bool not_good = false;
    
    if (begin > end)
    {
        printf("%ld isn't smaller than %ld.\n", begin, end);
        not_good = true;
    }
    if (begin < low || end <low)
    {
        printf("Values must be %ld or greater.\n", low);
        not_good = true;
    }
    if (begin > high || end > high)
    {
        printf("Values must be %ld or less.\n", high);
        not_good = true;
    }
    
    return not_good;
}

输出结果:

  • 程序清单8.8,menuette.c:

/*menuette.c -- 菜单程序 */ 
#include <stdio.h>

char get_choice(void);
char get_first(void);
int get_int(void);
void count(void);

int main(void)
{
    int choice;
    
    while ((choice = get_choice()) != 'q')
    {
        switch (choice)
        {
            case 'a': printf("Buy low, sell high.\n");
                      break;
            case 'b': putchar('\a');
                      break;
            case 'c': count();
                      break;
            default:  printf("Program error!\n");
                       break;
        }
    }
    printf("Bye.\n");
}

void count(void)
{
    int n, i;
    
    printf("Count how far? Enter an integer: \n");
    n = get_int();
    for (i = 1; i <= n; i++)
        printf("%d\n", i);
    while (getchar() != '\n')
        continue;
}

char get_choice(void)
{
    int ch;
    
    printf("Enter the letter of your choice: \n");
    printf("a. advice            b. bell\n");
    printf("c. count            q. quit.\n");
    ch = get_first();
    while ((ch < 'a' || ch > 'c') && ch != 'q')
    {
        printf("Please respond with a, b, c, or q.\n") ;
        ch = get_first();
    }
    
    return ch;
}

char get_first(void)
{
    int ch;
    
    ch = getchar();
    while (getchar() != '\n')
        continue;
        
    return ch;
}

int get_int(void)
{
    int input;
    char ch;
    
    while (scanf("%d", &input) != 1)
    {
        while ((ch = getchar()) != '\n')
            putchar(ch); //发现错误读空缓冲区并输出
        printf(" is not an integer.\nPlease enter an ") ;
        printf("integer value, such as 25, -178, or 3: ");
    }
    
    return input;
}

输出结果:

  • 编程练习

题目1,方法:统计字符数量。示例代码8_1.c:

#include <stdio.h>

int main(void)
{
    int ch, n;
    
    n = 0;
    printf("Please input some characters: ");
    while ((ch = getchar()) != '&')
        n++;
    printf("You have input %d of characters.\n", n);
    
    return 0;
}

输出结果:

题目2,方法:打印字符及其ASCII码。示例代码8_2.c:

#include <stdio.h>

int main(void)
{
    int ch;
    int n = 0;
    
    printf("Please input some characters: ");
    while ((ch = getchar()) != '&')
    {
        if (ch >= 32)
            printf("Ch:%c ASCII:%d ", ch, ch);
        else if (ch == '\n')
            printf("Ch:\\n ASCII:%d ", ch);
        else if (ch == '\t')
            printf("Ch:\\t ASCII:%d ", ch);
        else
            printf("Ch:^%c ASCII:%d ", ch + 64, ch);
        puts("\nYou can input again: ");
        if (++n == 10)
        {
            n = 0;
            putchar('\n');
        }
    }
    puts("\nDone.");
    
    return 0;
}

输出结果:

题目3,方法:统计不同类型字符数量。示例代码8_3.c:

#include <stdio.h>
#include <ctype.h>

int main(void)
{
    int ch;
    int upper = 0, lower = 0, other = 0;
    
    printf("Please inpute some characters: ");
    while ((ch = getchar()) != '&')
    {
        if (isupper(ch))
            upper++;
        else if (islower(ch))
            lower++;
        else
            other++;
    }
    printf("Upper:%3d\n", upper);
    printf("Lower:%3d\n", lower);
    printf("Other:%3d\n", other);
    
    return 0;
}

输出结果:

题目4,方法:统计字符串中单词数量。示例代码8_4.c:

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>

int main(void)
{
    char ch;             // 输入字符 
    int l_num, w_num;    // 字母、单词数量 
    float average;       // 平均每个单词字母数
    bool inword;         // 判断是否仍在单词内部 
    
    l_num = w_num = 0;
    average = 0.0;
    inword = false; 
    printf("Please input some characters(& to quit): ");
    while ((ch = getchar()) != '&')
    {
        if (isalpha(ch) )
        {
            l_num++;
            if (inword == false)
            {
                inword = true;
                w_num++;
            }
        }
        if (isspace(ch) || ispunct(ch))
        {
            inword = false;
        }
    }
    average = (float) l_num / w_num;
    printf("Characters: %-3d\n", l_num);
    printf("Words  num: %-3d\n", w_num);
    printf("Average   : %.2f\n", average);
    
    return 0;
} 

输出结果:

题目5,方法:二分查找猜数字。示例代码8_5.c:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h> 
#include <ctype.h>

void consumer(void);  //清空缓冲区 
bool character_check(void); //检测是否有非空字符并清空第一个非空字符及之前的缓冲区 
char get_choice(void); //将选择输入限制在合法区间并返回输入值 

int main(void)
{
    char ch, ch1;
    int min = 0, max = 100;
    int num;
    
    num = (min + max) / 2;
    printf("I guess the number you choose is %d, right?\n", num);
    while ((ch = get_choice()) != 'y')
    {
        printf("Is it bigger than %d?\n", num);
        ch1 = get_choice();
        if (ch1 == 'y')
            min = num + 1;
        else
            max = num - 1;
        num = (min + max) / 2;
        printf("Well, I guess the number you choose is %d, right?\n", num);
        
    }
    printf("Game over!\n");
    
    return 0;
}

void consumer(void)
{
    while (getchar() != '\n')
        continue;
}

bool character_check(void)
{
    char ch2;
    
    while ((ch2 = getchar()) != '\n') //第一个非空字符为回车,则读走回车 
        if (ch2 != '\t' && ch2 != ' ') //若第一个非空字符非回车,回车不被读走 
            return true;
            //break; //结束函数,无需break 
    
    return false;
}

char get_choice(void)
{
    char ch1;
    
    printf("Enter a character to choose(y or n): ");
    //防止第一个非空合法字符后出现第二个非空字符,例如assss 
    while (((ch1 = tolower(getchar())) != 'y' && ch1 != 'n') || character_check() == true)
    {
        if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t') // 使至少第一个非空字符被ch1获得 
            continue;
        else if (character_check() == true) //防止出现 fssss 这样的输入,即之前非法,之后合法,以及清空非空白字符缓冲区 
        {
            consumer(); 
            system("cls");
            printf("Selection illeal, try again: ");
            continue; 
        }
        // 输入a2这样的输入时执行 
        system("cls");
        printf("Selection illeal, try again: ");
    }
    
    return ch1;
}

输出结果:

题目6,方法:获取第一个非空白字符。示例代码8_6.c:

#include <stdio.h>
#include <ctype.h>

char get_choice(void);
char get_first(void);
int get_int(void);
void count(void);

int main(void)
{
    int choice;
    
    while ((choice = get_choice()) != 'q')
    {
        switch (choice)
        {
            case 'a': printf("Buy low, sell high.\n");
                      break;
            case 'b': putchar('\a');
                      break;
            case 'c': count();
                      break;
            default:  printf("Program error!\n");
                       break;
        }
    }
    printf("Bye.\n");
}

void count(void)
{
    int n, i;
    
    printf("Count how far? Enter an integer: \n");
    n = get_int();
    for (i = 1; i <= n; i++)
        printf("%d\n", i);
    while (getchar() != '\n')
        continue;
}

char get_choice(void)
{
    int ch;
    
    printf("Enter the letter of your choice: \n");
    printf("a. advice            b. bell\n");
    printf("c. count            q. quit.\n");
    ch = get_first();
    while ((ch < 'a' || ch > 'c') && ch != 'q')
    {
        printf("Please respond with a, b, c, or q.\n") ;
        ch = get_first();
    }
    
    return ch;
}

char get_first(void)
{
    int ch;
    
    do
    {
        ch = getchar();
    } while (isspace(ch)); //读取第一个非空白字符 
    while (getchar() != '\n')
        continue;
        
    return ch;
}

int get_int(void)
{
    int input;
    char ch;
    
    while (scanf("%d", &input) != 1)
    {
        while ((ch = getchar()) != '\n')
            putchar(ch); //发现错误读空缓冲区并输出
        printf(" is not an integer.\nPlease enter an ") ;
        printf("integer value, such as 25, -178, or 3: ");
    }
    
    return input;
}

输出结果:

题目7,方法:用字符代替数字选项。示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#define RANK1 8.75f
#define RANK2 9.33f
#define RANK3 10.00f
#define RANK4 11.20f
#define OVERTIME 40
#define TIMES 1.5f
#define BASE1 300
#define BASE2 150 
#define RAT_T1 0.15f
#define RAT_T2 0.20f
#define RAT_T3 0.25f
#define TAX1 (BASE1 * RAT_T1)
#define TAX2 (BASE2 * RAT_T2)

void show_menu(void); // 显示菜单 
void caculate(char choo, float t); // 计算并打印结果 
char choose_check(void); //将商品输入限制在合法区间并返回输入值 
void consumer(void); // 一旦判断非法后立刻读空缓冲区,避免多次读取失败和多次打印提现信息 
bool character_check(void); // 判断输入中除了数字和空白后面是否还有其它非法字符 

int main(void)
{
    char choose;
    float work_h = 1;
    
    while ((choose = choose_check()) != 'q')
    {
        system("cls") ;
        show_menu();
        printf("The selection you choose is %c.\n", choose);
        printf("Please input your working hours (0 to back): ");
        while (scanf("%f", &work_h) != 1 || work_h < 0 || character_check() == true)
        {
            consumer();
            printf("Working hour input illegal, Try again: ");
        }
        if (work_h == 0)
        {
            system("cls");
            continue;
        }
        caculate(choose, work_h);
    }
    printf("Done!\n");
    
    return 0;
}
 
void show_menu(void)
{
    printf("*****************************************************************\n");
    printf("Enter the number corresponding to the desired pay rate or action:\n");
    printf("a) $8.75/hr                        b)$9.33/hr\n");
    printf("c) $10.00/hr                       d)$11.20/hr\n");
    printf("q) quit\n");
}
 
void consumer(void)
{
    while (getchar() != '\n')
        continue;
}
 
bool character_check(void)
{
    char ch;
    while ((ch = getchar()) != '\n')
    {
        if (ch != '\t' && ch != ' ')
        {
            return true;
            break;
         }
     }
 
     return false;
}
 
char choose_check(void)
{
    char ch1;
    
    show_menu();
    printf("Enter a character to choose: ");
    //防止第一个非空合法字符后出现第二个非空字符,例如assss 
    while (((ch1 = tolower(getchar())) != 'a' && ch1 != 'b' && ch1 != 'c' && ch1 != 'd' && ch1 != 'q') || character_check() == true)
    {
        if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t') // 使至少第一个非空字符被ch1获得 
        { 
            continue;
        }
        else if (character_check() == true) //防止出现 fssss 这样的输入,即之前非法,之后合法,以及清空非空白字符缓冲区 
        {
            consumer(); 
            system("cls");
            show_menu();
            printf("Menu selection illegal, Try again: ");
            continue; 
        }
        // 输入a2这样的输入时执行 
        system("cls");
        show_menu();
        printf("Menu selection illegal, Try again: ");
    }
    
    return ch1;
}

void caculate(char choo, float t)
{
    float rank, total_in, tax, pure_in;
    
    if (choo == 'a')
        rank = RANK1;
    else if (choo == 'b')
        rank = RANK2;
    else if (choo == 'c')
        rank = RANK3;
    else
        rank = RANK4; 
    if (t > OVERTIME)
        t += (t - OVERTIME) * TIMES;
    total_in = rank * t;
    if (total_in <= BASE1)
        tax = total_in * RAT_T1;
    else if (total_in <= (BASE1 + BASE2))
        tax = TAX1 + (total_in - BASE1) * RAT_T2;
    else
        tax = TAX1 + TAX2 + (total_in - (BASE1 + BASE2)) * RAT_T3;
    pure_in = total_in - tax;
    printf("\nTotal income: %.2f\nTax: %.2f\nPure income: %.2f\n",
            total_in, tax, pure_in);
    printf("\nEnter to continue...");
    consumer();
    system("cls");
} 

输出结果:

题目8,方法:简易的计算功能。示例代码:

#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>

void show_menu(void);
void consumer(int n1);  //清空缓冲区 
bool character_check(int n2); //检测是否有非空字符并清空第一个非空字符及之前的缓冲区 
char choose_check(void); //将输入限制在合法区间并返回输入值
float float_check(void); //判断输入的浮点数是否合法 
void add(float num1,float num2); //加法运算 
void sub(float num1, float num2); //减法运算 
void mult(float num1, float num2); //乘法运算 
void divs(float num1, float num2); //除法运算 
char str1[1000], str2[1000]; //统计输入字符 
int k= 1, t = 0; //记录输入字符数 

int main(void)
{
    float a, b;
    char ch;
    
    a = b = 0;
    while ((ch = choose_check()) != 'q')
    {
        switch (ch)
        {
            case 'a':
                add(a, b);
                break;
            case 's':
                sub(a, b);
                break;
            case 'm':
                mult(a, b);
                break;
            case 'd':
                divs(a, b);
                break;
            default:
                printf("error.\n");
        }
    }
    
    return 0;
}

void show_menu(void)
{
    printf("****************************************\n");
    printf("Please choose the operation:\n");
    printf("a. add                      s. subtract\n");
    printf("m. multiply                 d. divide\n");
    printf("q. quit\n");    
}

void consumer(int n1)
{
    char cha;
    while ((cha = getchar()) != '\n')
    {
        if (n1 == 1)
            str1[k++] = cha;
        else if (n1 == 2)
            str2[t++] = cha;
    }
}

bool character_check(int n2)
{
    char ch2;
    
    while ((ch2 = getchar()) != '\n') //第一个非空字符为回车,则读走回车 
    {
        if (n2 == 1)
            str1[k++] = ch2;
        else if (n2 == 2)
            str2[t++] = ch2;
        if (ch2 != '\t' && ch2 != ' ') //若第一个非空字符非回车,回车不被读走 
        {
            return true;
        }
    }
    
    return false;
}

char choose_check(void)
{
    char ch1;
    
    show_menu();
    printf("\nEnter a character to choose: ");
    //防止第一个非空合法字符后出现第二个非空字符,例如assss 
    while (((ch1 = tolower(getchar())) != 'a' && ch1 != 's' && ch1 != 'm' && ch1 != 'd' && ch1 != 'q') || character_check(1) == true)
    {
        if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t') // 使至少第一个非空字符被ch1获得 
            continue;
        else if (character_check(1) == true) //防止出现 fssss 这样的输入,即之前非法,之后合法,以及清空非空白字符缓冲区 
        {
            consumer(1); 
            system("cls");
            show_menu();
            putchar('\n');
            str1[0] = ch1;
            //或者printf("%s is illegal, try again: ", str1); 
            for (int i = 0; i < k; i++)
                printf("%c", str1[i]);
            printf(" is illegal, try again: ");
            memset(str1, 0 ,sizeof(str1)); //初始化字符串数组 
            k = 1;
            continue; 
        }
        // 输入a2这样的输入时执行 
        system("cls");
        show_menu();
        putchar('\n');
        str1[0] = ch1;
        for (int i = 0; i < k; i++)
                //或者putchar(str1[i]);
            printf("%c", str1[i]);
        printf(" is illegal, try again: ");
        memset(str1, 0 ,sizeof(str1));
        k = 1;
    }
    
    return ch1;
}

float float_check(void)
{
    float number;
    int judge, s;
    //int len2, len3;
    char str3[100];
    char str4[100]; 
    
    judge = 0;
    s = 0;
    while ((judge = scanf("%f", &number)) != 1 || character_check(2) == true)
    {
        consumer(2); //防止出现 gg12 这样的输入,即之前非法,之后合法 
        putchar('\n');
//方法一:移动字符串
//        if (judge == 1)
//        {
//            sprintf(str3, "%g", number);
//            len2 = strlen(str2);
//            len3 = strlen(str3);
//            for (i = len2 + len3 - 1; i > len3 - 1 ; i--)
//                str2[i] = str2[--len2];
//            for (i = 0; i < len3; i++)
//                str2[i] = str3[i];
//        }
//        printf("%s is illegal, try again: ", str2);
//方法二:合并字符串 
        if (judge == 1)
        {
            sprintf(str3, "%g", number); //将number转换为字符串 
            for (int i = 0; i < (int) strlen(str3); i++) //若获取number成功,则存储number字符 
                str4[s++] = str3[i];
        }
        for (int i = 0; i < t; i++)
            str4[s++] = str2[i];
        printf("%s is illegal, try again: ", str4);
        memset(str2, 0 ,sizeof(str2));
        memset(str3, 0 ,sizeof(str3));
        memset(str4, 0 ,sizeof(str4));
        t = s = 0;
    }
    
    return number;
}

void add(float num1, float num2)
{
    float sum;
    
    printf("Please input first number: ");
    num1 = float_check();
    printf("Please input second number: ");
    num2 = float_check(); 
    sum = num1 + num2;
    printf("%g + %g = %g\n", num1, num2, sum);
    printf("Enter to continue...");
    consumer(0);
    system("cls");
}

void sub(float num1, float num2)
{
    float subn;
    
    printf("Please input first number: ");
    num1 = float_check();
    printf("Please input second number: ");
    num2 = float_check();
    subn = num1 - num2;
    printf("%g - %g = %g\n", num1, num2, subn);
    printf("Enter to continue...");
    consumer(0);
    system("cls");
}

void mult(float num1, float num2)
{
    float mul;
    
    printf("Please input first number: ");
    num1 = float_check();
    printf("Please input second number: ");
    num2 = float_check();
    mul = num1 * num2;
    printf("%g * %g = %g\n", num1, num2, mul);
    printf("Enter to continue...");
    consumer(0);
    system("cls");
}

void divs(float num1, float num2)
{
    float divn;
    
    printf("Please input first number: ");
    num1 = float_check();
    printf("Please input second number: ");
    while ((num2 = float_check()) == 0)
    {
        printf("Please input a number other than 0: ");
    }
    divn = num1 / num2;
    printf("%g / %g = %g\n", num1, num2, divn);
    printf("Enter to continue...");
    consumer(0);
    system("cls");
}

输出结果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值