C重复字符,逐个字符

时间:2016-10-18 19:02:50

标签: c char compare

我试图找出彼此跟随的两个字符是否是相同的字符。即如果我有这个输入“老女人”我想打印第二个D“复制”旁边。这是我的代码,但我无法找到如何进行此编码。这是我的代码:

void main()
{
    char ch,ch2;
    ch = getchar(); // getting the line of text
    int i = 1;
    ch2 = ch;

    while (ch != '\n') // the loop will close if nothing entered
    {
        if (ch == ch2[&i]) {
            printf("%c-duplicate", ch);
        }
        i++;
        if (ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') { // checking for uppaercase vowel
            printf("%c-upper case vowel", ch);
        }
        else if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') { // checking for lowecase vowel
            printf("%c-lower case vowel", ch);
        }
        else if (ispunct(ch)) {          // checking for punctuation
            printf("%c-punctuation", ch);
        }
        else
            putchar(ch);

            printf("\n");
            ch = getchar();
        }
        printf("\n");
    }
}

我将字符设置为另一个变量,然后使用第一个if语句检查它们。程序应该逐个字符地运行。

3 个答案:

答案 0 :(得分:1)

下面是一个我相信你想要的例子。 c是当前正在阅读的字符(注意:它是int类型),而c1是前一个字符读取(初始化为-1以确保它与第一个字符不匹配检验)。

虽然您可以比较AE ...,但字符串库提供了strchr,可以轻松地测试单个字符是否包含在更大的字符串中。

为什么不使用printf来构建包含适用于任何一个字符的所有条件的字符串,而不是为每个duplicatevowel等调用sprintf。 。这样,您只能在每次迭代结束时调用printf一次(取决于您是打印全部还是仅打印符合条件的那些)。 s用作保存每个字符的匹配信息的缓冲区,offset只是先前写入s的字符数。 (你应该检查以确保你没有超过s中可用的字符数(但这里不需要)

目前还不清楚是要在输入字符串中打印每个字符,还是只打印到目前为止匹配的字符。下面的代码只输出符合其中一个条件的字符(如果没有给出参数)。如果您想查看所有字符,则将任何值作为程序的第一个参数传递。

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

#define MAXL 32

int main (int argc, char **argv) {

    char *uvowel = "AEIOU", *lvowel = "aeiou";
    int c, c1 = -1;

    while ((c = getchar()) != '\n' && c != EOF) {
        char s[MAXL] = "";              /* description buffer */
        int offset = 0;                 /* offset       */
        if (c == c1)                    /* new == old   */
            offset = sprintf (s, " duplicate");
        if (strchr (uvowel, c))         /* upper-case?  */
            sprintf (s + offset, " upper-case vowel");
        else if (strchr (lvowel, c))    /* lower-case?  */
            sprintf (s + offset, " lower-case vowel");
        else if (ispunct (c))           /* punctuation? */
            sprintf (s + offset, " punctuation");
        else if (argc > 1)              /* if printing all */
            sprintf (s + offset, " other");
        if (*s)                         /* print c and s   */
            printf (" %c - %s\n", c, s);
        c1 = c;                         /* save last char read */
    }

    return 0;
}

示例使用/输出

$ echo "The oldd woman" | ./bin/classdup
 e -  lower-case vowel
 o -  lower-case vowel
 d -  duplicate
 o -  lower-case vowel
 a -  lower-case vowel

将任何值作为第一个参数传递以打印所有字符:

$ echo "The oldd woman" | ./bin/classdup 1
 T -  other
 h -  other
 e -  lower-case vowel
   -  other
 o -  lower-case vowel
 l -  other
 d -  other
 d -  duplicate other
   -  other
 w -  other
 o -  lower-case vowel
 m -  other
 a -  lower-case vowel
 n -  other

重复元音

$ echo "womaan" | ./bin/classdup
 o -  lower-case vowel
 a -  lower-case vowel
 a -  duplicate lower-case vowel

仔细看看,如果您有任何疑问,请告诉我。有很多方法可以做到这一点,这只是一个看似接近你意图的方法。

(注意:您需要传递-Wno-unused-parameter编译器选项以消除有关argv未使用的警告,或者只是在代码中的某处执行存根测试,例如if (argv[1]) {}

答案 1 :(得分:1)

值得回答尝试帮助理解我认为的变量和指针。

尝试回答。 。 。尽可能简单。 。 。 注意#1:主要问题是ch和ch2被声明为单个char变量。他们可以成为一个&#39;或者&#39; b&#39;或者&#39; \ n&#39;或0x20或任何其他单个字符。它们不是char数组或指针。你有一个评论,你读了一个字符&#39; ch = getchar()//获取文本行&#39;,该评论不正确(尽管你在显示你在你的例子中的想法时有很好的评论) ,无论如何,这个&#39; ch = getchar()&#39;只得到一个字符。稍后您将ch2视为数组。

char ch,ch2;
. . . then later:
if (ch == ch2[&i]) {   // ouch, does that even compile? yes. oh dear. how do we explain this one?! 

哎哟!这是错误的,因为它将ch2视为数组/指针。 你的循环现在的工作方式是将ch2设置为第一个char读取。它永远不会改变。

它可以编译好但是它会发出警告吗?实际上,公平对待你。我没有收到警告。 gcc 4.8.2非常满意ch2是一个char和做(ch == ch2 [&amp; i])。现在,ch2 [&amp; i]可能是语法上有效的代码,它将编译好。它甚至会运行正常。但是这是什么意思?它在语义上是否有效?让我们忘掉这个奇怪的事情,直到以后。

请注意,你可以让c编译好但是它可能会充满指针错误并且可能崩溃/挂起。所以。 。 。小心: - )。

尝试进行这样的更改:

ch = getchar(); // does not get the line of text, just gets one char
. . . 
ch2 = 0; // for the first iteration of loop
if (ch == ch2) { // change from ch2[&i] - wow :-) very confused!
. . . 
    ch2 = ch; // set ch2 to the last char read before reading new
    ch = getchar(); // read one new char

这使代码只使用2个字符。 ch和ch2。你不使用我。您不使用数组或字符串或char指针。

注意#1.1:ch2 [&amp; i]编译并运行。但是错了,OHHHH SOOOOOO错了。而且很奇怪。数组访问如何在c中工作? c [&amp; i]的语法是&#34;正确&#34; (可能取决于编译器)。但请不要使用这种语法!这是什么意思?这在语义上是可疑的。看起来或许意图是与我一起使用字符数组。快速示例显示正确分配和读取字符数组:

char s[100]; // string of 100 chars, accessing index below 0 and above 99 is bad
i=0;
s[i]='H';    // assign char 'H' to first letter of string (s[0])
i++;         // increment i, i is now 2.
s[i]='i';
i++;
s[i]=0; // end string
printf("s[0]=%c s[1]=%c s[2]=%02x string:%s",s[0],s[1],s[2],s);

注意#1.2:ch2 [&amp; i]编译并运行。如何以及为什么要编译?

&amp; i表示指向内存中变量i的指针

printf中的

%p将显示​​指针值

因此,请尝试将其添加到代码示例中:

printf("%p %p %p\n", &ch, &ch2, &i);

// ch2[i] will not compile for me, as ch2 is not an array. syntax error

// ch2[&i] DOES compile for me. But . . what is the value ? 
// What does it mean. I do not know! Uncharted territory.
printf("ch2[&i]:%p:%02x\n",&i,ch2[&i]);
printf("ch2[&ch]:%p:%02x\n",&ch,ch2[&ch]);
printf("ch2[&ch2]:%p:%02x\n",&ch2,ch2[&ch2]);

我得到这样的东西,每次运行指针改变:

ch2[&i]:0xbfa0c54c:bfa0de71
ch2[&ch]:0xbfa0c54a:08
ch2[&ch2]:0xbfa0c54b:00

发现的解释:

通常我们声明一个数组,例如&#39; int array [100];&#39;其中100是数组的大小。 array [0]是第一个元素,array [99]是最后一个元素。我们使用整数索引数组。现在,所有数组都是指针。 SO *数组与数组[0]相同。 *(array + 1)与array [1]相同。

到目前为止一切顺利。

现在*(1 +数组)也与数组[1]相同。 我们可以说int i = 7;并使用array [i]或*(array + 7)或*(7 + array)或i [array]来显示数组的第7个元素。我[数组]对任何程序员应该看起来非常非常错误(不是语法错误,但在哲学上/语义上/在道德上是错误的!)

好。精细。冷静。天啊。现在用&#39; char ch2;&#39; ch2是一个单一的char。它不是一个数组。 ch2 [&amp; i]工作(在编译中工作,有时/大多数运行正常!!!)因为最后一个(WROOOONG)i [数组]符号是有效的。看TYPES很有意思:

i[array] === <type int>[<type int *>]. 
ch2[&i] === <type char>[<type int *>]. 

C愉快而快乐地将char转换为int,int可以添加到指针或用作指针。最后的结论:语法ch2 [&amp; i]评估为偏移的整数:&amp; i(指向整数i的指针)char ch2的PLUS值。没有充分的理由使用这种语法!这是危险的。您最终访问的内存位置可能有效,也可能无效,因为您的指针指向单个变量,该位置在引用任何其他值时无效。

见这里:Why 'c[&i]' compiles while 'c[i]' doesn't?

注意#2:观看包围{}。 while和main closing}和缩进在示例中不匹配。程序运行正常,出现此错误。 putchar(ch)作为最后一个的一部分运行。之后的命令在while循环结束时运行。

注意#3 main应该返回int not void main可选择什么都不用&#39;()&#39;或&#39;(int argc,char ** argv)&#39;。

答案 2 :(得分:-1)

  1. 其他建议:改变ch == ch2 [&amp; i]这没有任何意义
  2. 由于你在循环之前设置ch = ch2然后是行 if(ch == ch2) (修复后)将始终在第一次评估为真时
  3. 你的其他,非常令人困惑,如果你有多行代码,你必须放在括号中
  4. 请记住,当您输入输入时,您实际上提交了两个字符,例如(“e”AND“\ n”),因为您在输入字符后按Enter键并计算
  5. 稍微努力一点,这意味着发出错误信息,记下您尝试解决方案的结果。它对我们和你都有帮助。这似乎有点像你写的这个,只是立即想要修复。编程越来越难,如果你无法解决问题(提出建议),那么它会受到更多的伤害,但它没有必要。
  6. 要快速进行脏概念验证,请添加另一个ch = getchar();在你的其他人之后立即。请注意,下面的代码应该运行但不能完全按照您的要求运行,您需要进行一些进一步的调试。

    编辑2016年10月19日

    修正了你们指出的char2问题

    将ch2 = ch移动到获得新角色的行上方

    #include <stdio.h>
    #include <ctype.h>
    
    int main(){
        char ch,ch2;
        ch = getchar(); // getting the line of text
        int i = 1;
        ch2 = 0;
    
        while (ch != '\n') // the loop will close if nothing entered
        {
            if (ch == ch2) {
                printf("%c-duplicate", ch);
            }
            i++;
            if (ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') { // checking for uppaercase vowel
                printf("%c-upper case vowel", ch);
            }
            else if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') { // checking for lowecase vowel
                printf("%c-lower case vowel", ch);
            }
            else if (ispunct(ch)) {          // checking for punctuation
                printf("%c-punctuation", ch);
            }
    
            printf("\n");
            ch2 = ch;
            ch = getchar();
            ch = getchar();
    
        }
    
    
        printf("\n");
        return 0;
    }