Worth answering to try and help understand variables and pointers I think.
To try and answer . . . as simply as possible . . . NOTE #1: the main problem/issue is that ch and ch2 are declared as single char variables. They can be 'a' or 'b' or '\n' or 0x20 or any other single char. They are NOT char arrays or pointers. You have a comment where you read one char 'ch = getchar() // getting the line of text', that comment is incorrect (although you do have good comments in showing what you are thinking in your example), anyway, this 'ch = getchar()' just gets a single char. Later you treat ch2 as an array.
char ch,ch2;
. . . then later:
if (ch == ch2[&i]) { // ouch, does that even compile? yes. oh dear. how do we explain this one?!
ouch! This is wrong because it treats ch2 as an array/pointer.
The way your loop is working now is ch2 is set once to the very first char read. And it never changes.
It may compile okay BUT does it give a warning? Actually, in fairness to you. I do not get a warning. gcc 4.8.2 is perfectly happy with ch2 being a char and doing (ch == ch2[&i]). Now, ch2[&i] may be syntactically valid code, it will compile ok. It will even run ok. BUT what does it mean? Is it semantically valid? Let's forget about this weird thing until later.
Note that you can have c compiling fine BUT it can be quite full of pointer errors and can crash/hang. So . . . be careful :-).
Try making a change like this:
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
This makes the code work just using 2 chars. ch and ch2. You do not use i. You do not use an array or string or char pointer.
NOTE #1.1: ch2[&i] compiles and runs. BUT IT IS WRONG, OHHHH SOOOOOO WRONG. And weird. How does array access work in c? The syntax of c[&i] is "correct" (maybe depends on compiler). BUT please do not use this syntax! What does it mean? It is semantically dubious. Looks like perhaps intent was to use array of chars together with i. Quick example showing assigning and reading from array of chars correctly:
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);
NOTE #1.2: ch2[&i] compiles and runs. How and why does it compile?
&i means the pointer to the variable i in memory
%p in printf will show pointer value
So try adding this to code sample:
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]);
I'm getting something like this each run the pointers change:
ch2[&i]:0xbfa0c54c:bfa0de71
ch2[&ch]:0xbfa0c54a:08
ch2[&ch2]:0xbfa0c54b:00
The discovered explaination:
Usually we declare an array e.g. 'int array[100];' where 100 is the size of array. array[0] is first element and array[99] is the last. We index the array using integer. Now, all arrays are pointers. SO *array is the same as array[0]. *(array+1) is the same as array[1].
So far so good.
Now *(1+array) is also the same as array[1].
We can say int i=7; And use array[i] or *(array+7) or *(7+array) OR i[array] to show the 7th element of the array. i[array] to any programmer should look very VERY WROOOONG (not syntactically wrong BUT philosophically/semantically/morally wrong!)
Okay. Fine. Calm down. Jeez. Now with 'char ch2;' ch2 is a single char. It is NOT an array. ch2[&i] works(works as in compiles and sometimes/mostly runs ok!!!) because the last(WROOOONG) i[array] notation is valid. Looking at TYPES is interesting:
i[array] === <type int>[<type int *>].
ch2[&i] === <type char>[<type int *>].
C happily and merrily casts char to int and int can be added to pointer or used as pointer. SO FINALLY IN CONCLUSION: the syntax ch2[&i] evaluates to an integer at offset of: &i(pointer to integer i) PLUS value of char ch2. There is no good reason to use this syntax! It's DANGEROUS. You end up accessing a memory location which may or may not be valid and as your pointer is pointer to single variable the location in not valid in reference to any other values.
See here: Why 'c[&i]' compiles while 'c[i]' doesn't?
NOTE #2: watch the bracketing {}. while and main closing } and indentation do not match in example. The program functions okay with this error. The putchar(ch) runs as part of the last else. The commands after that run at end of while loop.
NOTE #3 main should return int not void main optionally takes nothing '()' or '(int argc, char**argv)'.