C重复字符,逐个字符

我试图找到彼此跟随的两个字符是否是相同的字符。 即如果我有这个输入“老女人”我想打印第二个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语句检查它们。 程序应该逐个字符地运行。

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

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

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

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

 #include  #include  #include  #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:主要问题是ch和ch2被声明为单个char变量 。 它们可以是’a’或’b’或’\ n’或0x20或任何其他单个字符。 它们不是char数组或指针。 你有一个评论,你读了一个字符’ch = getchar()//得到文本行’,评论是不正确的(虽然你在你的例子中显示你在想什么时有很好的评论),无论如何,这个’ ch = getchar()’只获取一个char。 稍后您将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 [&i])。 现在,ch2 [&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 [&i]编译并运行。 但是错了,OHHHH SOOOOOO错了。 而且很奇怪。 数组访问如何在c中工作? c [&i]的语法是“正确的”(可能取决于编译器)。 但请不要使用这种语法! 这是什么意思? 这在语义上是可疑的。 看起来或许意图是与i一起使用字符数组。 快速示例显示正确分配和读取字符数组:

 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]=%cs[1]=%cs[2]=%02x string:%s",s[0],s[1],s[2],s); 

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

&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 

发现的解释:

通常我们声明一个数组,例如’int array [100];’ 其中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个元素。 我[数组]对任何程序员应该看起来非常非常错误(不是语法上的错误,但在哲学上/语义上/在道德上是错误的!)

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

 i[array] === []. ch2[&i] === []. 

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

看到这里: 为什么’c [&i]’编译而’c [i]’没有?

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

注意#3 main应返回int not void main可选择不带’()’或’(int argc,char ** argv)’。

  1. 其他建议:改变ch == ch2 [&i]这在这里没有意义
  2. 由于你在循环之前设置ch = ch2然后行if(ch == ch2)(修复之后)总是第一次评估为true
  3. 你的其他内容非常令人困惑,如果你有多行代码,你必须放在括号中
  4. 请记住,当您输入输入时,您实际上提交了两个字符,例如(“e”AND“\ n”),因为您在键入字符后按Enter键并且计数
  5. 尝试稍微努力,意味着发出错误消息,记下您尝试解决方案的结果。 它对我们和你都有帮助。 这似乎有点像你写的这个,只是立即想要修复。 编程越来越难,如果你无法解决问题(提出建议),那么它会受到更多的伤害,但它没有必要。

要快速进行脏概念validation,请添加另一个ch = getchar(); 在你的其他人之后立即。 请注意,下面的代码应该运行但不能完全按照您的要求运行,您需要进行一些进一步的调试。

编辑2016年10月19日

修复了你们指出的char2问题

将ch2 = ch移动到获得新字符的行上方

 #include  #include  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; }