Is this a valid for loop? - c++

I'm currently learning c++ and i cant get my head around this syntax for the for loop.
I'm aware that for(<T>: <V>) (for-each) and the standard for(init; cond; incr) but i haven't come across the following before
for (char ch; cin>>ch && !isdigit(ch); )
If someone could shed some light onto it it would be greatly appreciated!

for (char ch; cin>>ch && !isdigit(ch); )
^^ A ^^ ^^^^^^^^ B ^^^^^^^^^^^^ ^ C ^
A: Is the init section but in this case it only declared a char named ch
B: Is the condition section executed on each iteration
It starts be taking a single character as input and then continues looping if it is not a digit
C: Is the increment section but is empty, the condition section is relied upon to get the next input (i.e., the increment) and cause the loop's termination

This is the same syntax as your second example:
for ( init ; cond ; incr)
for (char ch; cin>>ch && !isdigit(ch); )
This just default-initializes a char, then reads a new value in and ensures it's a digit each iteration.

for (char ch; cin>>ch && !isdigit(ch); )
Is your standard 3 part for loop. char ch; declares a char called ch. The condition of the the loop is the result of cin>>ch logically and with !isdigit(ch) and there is nothing being incremented.
The result of this for loop is it will read in input until the input is a digit or it reaches the end if the input.
A for loop does not need to have something in each part. As an extreme if you write for(;;) you would have a loop that runs forever.

It is.
The first value is simply an initialization value (char ch will remain unchanged, but simply be defined).
The second value is a value that has to be true for the loop to end (condition) - so until cin >> ch is not null (it gains a value) and until ch isn't a digit, it will run.
The third parameter is an increment, that is a void in your case, so nothing happens.
EDIT: I remember back in C++ classes in 1st year of college, my teacher would do something like:
for(int i = 0; i < 10; cout << array[i++]);
and basically shrinking the code by a line.

Related

Why is the first digit of a string still read and output in a while loop where the condition !isdigit is false?

Note: I know the solution that would solve the issue, but I don't understand the "computer logic," or what is going on behind the compiler.
In my C++ textbook, there is a blurb of example code that reads:
cout << "Enter a line of input:\n";
char next;
while ((!isdigit (next)) && (next != '\n'))
{
cin.get (next);
cout << next;
}
cout << "<END OF OUTPUT>";
... Paired with the example input: I'll see you at 10:30 AM.
I would expect, after typing in the input, for the output to be I'll see you at <END OF OUTPUT>. Instead, the first digit, "1," is also output, such that it becomes I'll see you at 1<END OF OUTPUT>. Why is this? Is this because the statement cin.get (next); is not declared/initialized outside of the while loop, and thus the first next value tested in the while loop's conditional parameters is not actually the first character of the keyboard input? Or does the while loop run an extra iteration when the next condition is not satisfied?
If it's the former, what does the computer test if next is not set to a value? And why does the first digit ("1") read still meet the condition to run the loop again one more time before terminating?
As mentioned in the comments, you have to initialize next before using it, otherwise it is undefined behavior.
Now lets assume, next is properly initialized to a non-digit character. The condition (!isdigit (next)) && (next != '\n') is checked once when you enter the while loop and every time when you reach the end of the statement in curly braces. In your first version, you get a new char and immediately stream it to cout. The check is done afterwards and the loop terminates as expected.

Don't understand why while(*ptr++) enter while loop for 0 value (string terminator)

I have a problem with the following apperently trivial sample code:
(on visual studio 2015)
Please ignore the part with pointing to a literal constant, possible warnings or erros on the newwer compiler, that is not what I don't understand.
My problem is why it prints '0' and how the while loop works, tried using both debugger and printf. My understanding of the problem is this:
moves ptr to point at 'e'
checks content of ptr which is 'e' it is not 0 so it enters while loop
back to condition line, moves ptr to 'l'
checks *ptr, it is not 0, enters...
blah blah for the letters l, o
Then it increases ptr after 'o' and gets '\0', at which point by my logic it should NOT enter the loop, but i does, and no longer enters after one more step when it is pointing over the terminator at junk?!?
I looked over 2 other topics, this topic about operator precedence and this one about the while(*ptr) case going over the terminator, but I don't understand from the second WHY it enters the loop and thy it increases the pointer value afterwards? for what i understand the order is first increase pointer, then get the value with *
#include <cstdio>
#include<stdlib.h>
int main(void) {
char* str = "hello";
char* ptr = str;
char least = 127;
while (*ptr++) {
printf("%c-", *ptr);
least = ((*ptr) < (least)) ? (*ptr) : (least);
}
printf("%d\n", least);
}
Inside the loop you're not using the same character that you tested in the while condition.
Since ptr++ is a post-increment, it returns the current value of ptr and then increments it. So when ptr points to the o character, and you do
while (*ptr++)
it tests 'o', which is not zero, so it will enter the loop. But after the test it increments ptr to point to the next character, so now it points to '\0'. Then it prints this character and sets least to it.
You should increment the pointer after processing it. You can do this by moving ptr++ to the end of the loop body. Or you can use a for loop instead of while:
for (ptr = str; *ptr; ptr++)
The last printf call outputs the terminating zero of the string literal as an integer.
To make it clear consider a string literal with one actual character as for example "A".
Before the first iteration of the while loop
while (*ptr++)
{
printf("%c-", *ptr);
least = ((*ptr) < (least)) ? (*ptr) : (least);
}
the pointer ptr points to the character 'A' of the string literal. This expression
*ptr++
can be imagined like
char c = *ptr;
++ptr;
So the control passes to the body of the loop because 'A' is not equal to zero. Meantime the pointer ptr was increased after evaluation the condition. So now it points to the terminating zero '\0' of the string literal.
As 0 is less than 123 then the variable least gets the value 0.
least = ((*ptr) < (least)) ? (*ptr) : (least);
In the next iteration of the loop ptr still points to the terminating zero. So the control bypasses the body of the loop and the zero is outputted in the next statement after the loop.
From the C Standard (6.5.2.4 Postfix increment and decrement operators)
2 The result of the postfix ++ operator is the value of the
operand. As a side effect, the value of the operand object is
incremented (that is, the value 1 of the appropriate type is added to
it).

C++: How does a for loop like this one work (using pointers)?

I just came across this for loop in a reference book but I'm not really sure what's going on in the comparison since it's just a lone pointer.
char input[300], *p, *q[300], **r = q;
cin.getline(input, 300);
for (p = input; *p; p++)
How would it work?
input is a null-terminated string. cin.getline will place a 0 after the last character of the read string or at input[299] if the line exceeds 299 characters.
The char value gets implicitely converted to a boolean. It becomes true if it's not zero and consequently false if it's zero. Thus the loop condition is equivalent to *p != 0.
Therefor the loop will iterate over the array until it comes across a zero, the end of the string.
The second expression in a for statement is evaluated for "truthiness". A character is true if is not equal to 0. The for loop could be changed to the following equivalent one:
for (p = input; *p != 0; p++)
Since strings are null-terminated, this is how one iterates through the characters in a string, and stop at the end.

Input in array without adding increment operator ++

I would like some confirmation (or refutation) about something.
I was just busy with a simple exercise placing statements inside loop conditionals. Basically I created an array of 5 elements and then have the user input 5 values that will be stored in the array. Pretty basic stuff. But then I started wondering: What if I replaced the a[i++] in my code with simply a[i]? So I did, and the resultant output was that I (i.e. the user) just kept inputting values seemingly infinitely, i.e. not stopping at only 5 inputs.
Now then I made the assumption that what might be happening is that now the program simply replaces every new input value with the previous one and storing it in element 0 of the array, over and over, hence it not stopping at 5.
Is this assumption of mine is correct? If not, then please shed some light on what exactly is happening here. This might be a very nonsensical thing to be concerned about, but I'd really like to know either way.
//array test
#include <iostream>
int main()
{
int a[5] = { 0 };
int i = 0;
while(std::cin >> a[i++] && i < 5);
return 0;
}
So, you are basicly asking what's the difference between i and i++? It's rather basic C/C++ (note the ++ here!). I suggest you google for "C++ postincrement operator" :)
If you remove the i++ and replace it with only i, you are replacing a[0] indefinitely.
a[i++] evaluaves to a[i], and AFTER that increases i by one. So when i reaches 5, the second part of your condition (i<5) is not true and exits from the while loop.
Yes, you're correct.
Just test it, remove the ++ and run.
If you want "having a loop with no code inside", do not use std::cin >> a[i++] expression as condition (I think it will always true). Better use comma operation, e.g.:
while(std::cin >> a[i++], i < 5);
Moreover, in the condition expression like (std::cin >> a[i++]) && (i < 5) left part (i.e. (std::cin >> a[i++])) can be skipped because optimization done by compiler (so i++ will not be executed).

Exercise Self Study Help

I've started learning C++ and am working through some exercises in the C++ Primer Plus book.
In chapter 5 one of the exercises is:
Write a program that uses an array of
char and a loop to read one word at a
time until the word done is entered.
The program should then report the
number of words entered (not counting
done). A sample run could look like this:
Enter words (to stop, type the word done):
anteater birthday category dumpster
envy finagle geometry done for sure
You entered a total of 7 words.
You should include the cstring header
file and use the strcmp() function to
make the comparison test.
Having a hard time figuring this out. It would be much easier if I could use if statements and logical operators but I'm restricted to using only:
Loops
Relational Expressions
char arrays
Branching statments (ie if, case/switch ) and logical operators are not allowed.
Can anyone give me hints to push me in the right direction?
Edit: Clarification. The input must be one string. So, several words for one input.
Edit: oops, spec says to read into an array of char… I'm not going to bother editing, this is really stupid. std::string contains an array of char too!
cin.exceptions( ios::badbit ); // avoid using if or && to check error state
int n;
string word;
for ( n = 0; cin >> word, strcmp( word.c_str(), "done" ) != 0; ++ n ) ;
I prefer
string word;
int n;
for ( n = 0; cin && ( cin >> word, word != "done" ); ++n ) ;
Use this pseudo-code:
while (input != done)
do things
end-while
HINT: A loop could also act as a conditional...
integer count
char array input
count = 0
read input
while(input notequal "done")
count++
read input
done
print count
The input notequal "done" part can
be done as strcmp(input,"done"). If
the return value is 0 is means
input is same as "done"
reading input can be done using cin
You should define a max len for char arrays first. Then a do while loop would be sufficient. You chould check the string equality with the strcmp function. That should be ok.