如何检查C中的stdin == stdout

时间:2018-02-17 05:36:28

标签: c stdout stdin getchar putchar

我正在构建一个程序,它接受用户输入,操作它并输出更改(如果有的话)。准则是:

  1. 删除所有数字
  2. if>连续2个换行,仅打印2
  3. 更改字母案例
  4. 为每个空间打印2个空格
  5. 通常打印所有其他字符
  6. 如果stdin和stdout相同则从main返回1,否则返回0。
  7. 我不能为这个项目使用任何数据结构,所以我使用getchar()来读取char的stdin char。

    有没有办法在st中将stdin与stdout进行比较?我是语言的新手,不知道如何调查这个。所有指南满足sans 6的代码如下:

    #include <stdio.h>
    
    int newline(int iochar);
    void testChars(int iochar);
    void upperCase(int iochar);
    void lowerCase(int iochar);
    void space(int iochar); 
    void digit();
    
    
    int main()
    {
        int iochar = 0;
        iochar = getchar();
    
        testChars(iochar);
    
        return 0;
    }
    
    void testChars(int iochar)
    {
        while(iochar != EOF) {
            if (iochar == 10)
                iochar = newline(iochar);
    
            else if(iochar == 32)
            space(iochar);
    
            else if (iochar > 64 && iochar < 91)
            upperCase(iochar);
    
            else if (iochar < 123 && iochar > 96)
            lowerCase(iochar);
    
            else if (iochar < 58 && iochar > 47)
            digit();
    
            else putchar(iochar);
    
            iochar = getchar();
        }
    }
    
    void space(int iochar)
    {
        putchar(iochar);
        putchar(iochar);
    }
    
    int newline(int iochar)
    {
        int count = 0;
        while (iochar == 10){
            if(count < 2)
                putchar(iochar);
            count++; 
            iochar = getchar();
        }
        return iochar;
    }
    
    void digit()
    {
        return;
    }
    
    void upperCase(int iochar)
    {
        iochar += 32;
        putchar(iochar);
    }
    
    void lowerCase(int iochar)
    {
        iochar -=32;
        putchar(iochar);
    }
    

2 个答案:

答案 0 :(得分:1)

虽然您可以将测试分解为多个函数,但由于您处理的案例数量有限,只需将测试直接包含在一个“状态”循环中,该循环可跟踪换行符的数量以及是否存在对输入的任何修改都是同样可读的方式。 (很好地捕捉了关于XY问题的@iBug)。

有很多方法可以解决角色分类问题,这实际上就是你所拥有的。 (意思是你读了一个字符,分类是否适合某些预定义的测试,然后根据它的分类方式采取一些行动)。处理它的一种有效方法是使用循环来跟踪事物的状态(例如“已经按顺序读取了多少换行符?”,或者我是否在一个单词内,读取空格等等。)通过设置,或者重置或增加一些跟踪您感兴趣的条件(或状态)的变量,这些变量基于当前字符以外的其他内容。

您只需弄清楚您需要遵循的内容(此处,顺序换行符的数量,以及您是否以任何方式修改了输出)。这很简单,只需按照nl这样的整数读取连续换行的计数,并保留一个整数标记,如果进行任何更改,请将其设置为modified或其他逻辑。当您阅读“'\n'以外的任何内容时,重置您的换行计数,例如nl = 0;

然后只需要阅读输入的每个字符,直到遇到EOF并进行大量测试以确定您阅读的字符(使用if, else if, else或使用{{1}声明)。然后对于每个不同的测试,采取适当的行动。

例如,您可以通过以下简单的方式满足您的标准:

switch

注意:尝试避免在代码中使用幻数。如果您需要#include <stdio.h> int main (void) { int c, modified = 0, nl = 0; while ((c = getchar()) != EOF) { /* loop over each char */ if (c == '\n') { /* am I a '\n'? */ if (nl < 2) /* have I ouput less than 2? */ putchar ('\n'); /* output the newline */ else modified = 1; /* set modified flag */ nl++; /* update the number seen */ continue; /* get next char */ } else if ('A' <= c && c <= 'Z') { /* am I uppercase? */ putchar (c + 'a' - 'A'); /* convert to lowercase */ modified = 1; /* set modified flag */ } else if ('a' <= c && c <= 'z') { /* am I lowercase? */ putchar (c + 'A' - 'a'); /* convert to uppercase */ modified = 1; /* set modified flag */ } else if (c < '0' || '9' < c) { /* am I not a digit? */ if (c == ' ') { /* am I a space ? */ putchar (c); /* output extra space */ modified = 1; /* set modified flag */ } putchar (c); /* output unmodified char */ } nl = 0; /* reset newlines seen to zero */ } return modified ? 0 : 1; /* 0 - modified, 1 - stdout == stdin */ } 的ASCII值,请使用'A',而不是'A'。阅读分散了幻数的思想代码(例如656532并不像10那样提供信息,{{1 }和'A')。

另请注意,您可以使用宏' '(例如'\n'ctype.hisupper()等。)来轻松测试当前字符的位置一种非常易读的方式。手动操作以了解islower()中的那些方便功能实际正在做什么并练习正确设置条件测试也具有学习价值。

示例输入文件

现在只需创建一个测试用例来练习角色分类,并确保循环按照应有的方式工作。没有什么特别要求。而不是试图构建无数的isdigit()语句,只需创建一个具有适合每种情况的字符的输入文件:

ctype.h

示例使用/输出

然后仔细检查输出:

assert()

检查返回值

并验证$ cat dat/stateloop.txt This Is a Line followed by THREE-newlines and with SEVEN single-spaced asterisk * * * * * * * aND a lINE fOLLOWED bY five nEWLINES ('\N') And A Few Numbers zERO-tO-nINE (123456789) 1 a b c d e f g - A B C D E F G Done2Day 是否正确。

$ ./bin/stateloop <dat/stateloop.txt
tHIS  iS  A  lINE  FOLLOWED  BY  three-NEWLINES

AND  WITH  seven  SINGLE-SPACED  ASTERISK  *  *  *  *  *  *  *
And  A  Line  Followed  By  FIVE  Newlines  ('\n')

aND  a  fEW  nUMBERS  Zero-To-Nine  ()

A  B  C  D  E  F  G  -  a  b  c  d  e  f  g
dONEdAY

尝试A(不变)案例

对未修改的案例做同样的事情:

return

检查适当的退货

$ echo $?
0

如前所述,有很多方法可以解决这类问题。只需找到符合逻辑,强大,可读和易懂的内容。祝你的编码好运。

答案 1 :(得分:0)

您似乎正面临着XY问题。

根据您的描述,我读到您要做的实际操作是来检查输出是否与输入相同。因此解决方案很简单:您只需要跟踪在此过程中是否至少修改了一个字符,如果是,那么您就知道输入和输出会有所不同。

int modified = 0;

void testChars(int iochar){
    while(iochar != EOF){
        if (iochar == 10){
            iochar = newline(iochar);
        } else if(iochar == 32) {
            space(iochar);
            modified++;
        } else if (iochar > 64 && iochar < 91) {
            upperCase(iochar);
            modified++;
        } else if (iochar < 123 && iochar > 96) {
            lowerCase(iochar);
            modified++;
        } else if (iochar < 58 && iochar > 47) {
            digit();
            modified++;
        } else {
            putchar(iochar);
            // Nothing modified
        }

        iochar = getchar();
    }
}

int newline(int iochar){
    int count = 0;
    while (iochar == 10){
        if (count < 2) {
            putchar(iochar);
        } else {
            modified++;
        }
        count++; 
        iochar = getchar();
    }
    return iochar;
}

然后测试是否modified == 0并且您知道它。