如何检查C中的stdin==stdout
我正在构建一个程序,它接受用户输入,对其进行操作,并输出更改(如果有)。指引包括:如何检查C中的stdin==stdout,c,stdout,stdin,getchar,putchar,C,Stdout,Stdin,Getchar,Putchar,我正在构建一个程序,它接受用户输入,对其进行操作,并输出更改(如果有)。指引包括: 删除所有数字 如果一行中有两行以上的换行符,则仅打印两行 换箱 为每个空格打印2个空格 正常打印所有其他字符 如果标准输入和标准输出相同,则从main返回1,如果不相同,则返回0 我不能为这个项目使用任何数据结构,所以我使用getchar()逐字符读取stdin字符 有什么方法可以比较C中的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);
}
#包括
int换行符(int iochar);
void testChars(int iochar);
无效大写字母(int-iochar);
无效小写字母(int-iochar);
空隙空间(int-iochar);
空数字();
int main()
{
int iochar=0;
iochar=getchar();
testChars(iochar);
返回0;
}
void testChars(int iochar)
{
while(iochar!=EOF){
if(iochar==10)
iochar=换行符(iochar);
else if(iochar==32)
空间(iochar);
else if(iochar>64&&iochar<91)
大写字母(iochar);
else if(iochar<123&&iochar>96)
小写(iochar);
else if(iochar<58&&iochar>47)
数字();
else-putchar(iochar);
iochar=getchar();
}
}
无效空间(int iochar)
{
putchar(iochar);
putchar(iochar);
}
int换行符(int iochar)
{
整数计数=0;
while(iochar==10){
如果(计数<2)
putchar(iochar);
计数++;
iochar=getchar();
}
返回iochar;
}
无效数字()
{
返回;
}
无效大写字母(int-iochar)
{
iochar+=32;
putchar(iochar);
}
void小写(int iochar)
{
iochar-=32;
putchar(iochar);
}
您似乎面临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;
}
int-modified=0;
void testChars(int iochar){
while(iochar!=EOF){
if(iochar==10){
iochar=换行符(iochar);
}else if(iochar==32){
空间(iochar);
修改的++;
}else if(iochar>64&&iochar<91){
大写字母(iochar);
修改的++;
}else if(iochar<123&&iochar>96){
小写(iochar);
修改的++;
}else if(iochar<58&&iochar>47){
数字();
修改的++;
}否则{
putchar(iochar);
//没有修改
}
iochar=getchar();
}
}
int换行符(int iochar){
整数计数=0;
while(iochar==10){
如果(计数<2){
putchar(iochar);
}否则{
修改的++;
}
计数++;
iochar=getchar();
}
返回iochar;
}
然后,如果
modified==0,您就会知道它。您可以将测试分解为多个函数,因为您处理的案例数量是有限的,只需将测试直接包含在一个“状态”中即可跟踪换行数以及是否对输入进行了任何修改的循环是一种同样可读的方法。(在XY问题上@iBug捕捉得很好)
有许多方法可以解决字符分类问题,这基本上就是您所拥有的。(这意味着您读取一个字符,分类是否符合某个预定义的测试,然后根据其分类方式采取一些措施)。一种有效的处理方法是使用循环,通过设置、重置或增加跟踪任何条件(或状态)的几个变量来跟踪事物的状态(例如,“顺序读取了多少新行?”,或者我是否在单词内部、读取空格等)您感兴趣的是基于当前角色以外的内容
您只需找出需要遵循的内容(这里是顺序换行的数量,以及是否以任何方式修改了输出)。很简单,只需保留一个整数(如nl
)中读取的顺序换行计数,并保留一个整数标志,如果您进行了任何更改,请将其称为modified
或其他逻辑标记。当您读取除'\n'
以外的任何内容时,请重置换行计数,例如nl=0代码>
然后,只需读取输入的每个字符,直到遇到EOF
,并进行大量测试以确定读取的字符(使用if、else-if、else
或使用开关
语句)。然后针对每个不同的测试,采取适当的措施
例如,您可以通过以下简单的方式满足您的标准:
#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 */
}
示例使用/输出
然后仔细检查输出:
$ ./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
尝试一个(不改变)案例
对未修改的案例执行相同的操作:
$ printf "~@##$@#$%%#*[]{};:^^&&*)\n" | ./bin/stateloop
~@###$%#*[]{};:^^&&*)
检查适当的退货
$ echo $?
1
如前所述,有许多方法可以解决这类问题。只要找到符合逻辑、健壮、可读和可理解的东西。祝你的代码好运。你可以使用这样的字符“代码>‘a’/代码>-我们不记住ASCII值-所以你的代码的可读性是零。你是什么意思?比较代码< STDIN < /代码>与<代码> STDUD/<代码>?代码>更容易理解。它在ASCII和(对于那些怀旧的程序员)中工作。标准方法是iochar=tolower(iochar)
(6)以其最简单的形式if(stdin==stdout)返回1代码>应该
$ printf "~@##$@#$%%#*[]{};:^^&&*)\n" | ./bin/stateloop
~@###$%#*[]{};:^^&&*)
$ echo $?
1