Multiple conditions in while loop using && - c++

What works:
ifstream in("CallHello.cpp");
while(in >> s) {
if(s=="cout")
count++;
}
cout<<"Number of words : "<<count<<endl;
Output is 1 here which is correct.
What doesn't work
ifstream in("CallHello.cpp");
while(in >> s && s == "cout") {
count++;
}
cout<<"Number of words : "<<count<<endl;
Output is 0, for the above which is wrong.
Why adding another condition in the while using && gives the wrong output?

the first condition will continue looping while in has something to put on s, the second condition where you use while(in >> s && s == "cout") will only work if the first time you retrieve a value for s has a string of "cout" then it will run the block, therefore, your first value in s is not also "cout" the first time, so it just never loops.

Here is the reason why:
string s;
int count = 0;
while (in >> s && s == "cout") { // Ops: s == ""
++count; // while condition is false!
} // loop is skipped!
cout<<"Number of words : "<<count<<endl; // count was never incremented
// Output is 0

Related

A loop never starts

I'm writing a simple function that is supposed to read an input from a user as a string. Check if the strings solely consist of digits then converts it to and int and returns it. The problem is the loop never used regardless of the input. I'm struggling to find the root of the problem.
int correctInt()
{
string temp;
int input;
bool m;
do
{
m = false;
getline(cin, temp);
int length=temp.length();
for (int a = 0; a < length; a++)
{
if (temp[a] < '0' && temp[a]>'9')
{
cout << "ID should consist of numbers. Try again: ";
m = true;
break;
}
}
if (!m)
{
return input = atoi(temp.c_str());
}
} while (1);
}
Thank you in advance
You should use OR instead of AND:
temp[a] < '0' || temp[a]>'9'
Try to change && (and) condition to || (or) condition
if (temp[a] < '0' || temp[a]>'9')

What does >> do when used with string stream?

I was reading the following code sample:
std::array<int, 4> parseMessage(const std::string& input) {
std::stringstream ss(input);
std::array<int, 4> message;
int n;
// Loop over all characters in the string and ignore the semicolons.
for (int i = 0; ss >> n && i < 4; ++i) {
message[i] = n;
if (ss.peek() == ';') {
ss.ignore();
}
}
return message;
}
Can someone explain why someone would do ss>>n in the loop condition area ? It looks a bit odd to me.
It will first read a an int from the stream and then evaluate if the stream is good. (because s >> n will return a reference to s).
Evaluating a stream as bool:
Returns true if the stream has no errors and is ready for I/O operations. Specifically, returns !fail().
So as soon as the stream fails to read an int or reaches the end of stream (e.g. end of input) it will evaluate as false and end the loop.
So this code will extract up to 4 ints from a given input (4, because of the && i < 4).
>> reads into the variable on the right hand side of the expression and returns the stream.
Using a stream in a boolean expression returns whether the stream has not failed.
Your for loop is therefore equivalent to:
int i = 0;
while ( i < 4 )
{
ss >> n;
if ( ss.fail() )
{
break;
}
message[i] = n;
if (ss.peek() == ';') {
ss.ignore();
}
i++;
}
It reads up to 4 numbers and stops if the contents of the stream are not convertible to a number.

My c++ array value don't want to change, it output infinite loop

Normally, if line[num] is '>', it must add 1 to num to pass to the next character of the array and must output the corresponding character, but instead it infinitely output the sign '>'. Why?
//part of the code
line[] = {'>', '>', '#'};
circuit = line[num];
while(true)
{
if(circuit == '>')
{
num++; //add 1 to num
cout << circuit;
} else if(circuit == '<')
{
num--; //substract 1 to num
cout << circuit;
} else if(circuit == '#')
{
break;
}
also num is 0.
You declare circuit = line[num]; and then update num but you don't change the value of circuit which is already defined. In your if statements you can do circuit = line[num++];, do
num++;
circuit = curcuit[num]
Or keep what you have and put curcuit = curcuit[num] at the very top of your while loop before any of the conditionals are met.
`
In your loop, you never update circuit. So it will forever loop with the same character and execute the same if-branch !
It’s not either clear if num is initialized somewhere. Furthermore, it’s not clear how you’ll find the end of your array.
So better make line a string and consider a loop like:
for (int i=0; num<line.size(); i++) {
circuit=line[i];
...
}
And please do not go backward in the index: so i for exploring the chars and num for the sum

Reading a list of characters and storing in an array

I am having issues with the following code and I cant figure out why out of loop is not being printed. With this code I want the program to ignore any spaces inputted by the user and after a space is inputted the number previously entered is stored in an array location. Like this I want 6 and 78 to be stored in 2 array locations not store them individually as 6 7 8.
This is my code:
while ((in=getchar()) != '0')
{
if (in == ' ')
{
printf("space\n ");
continue;
}
else
{
printf("assigning\n ");
input[i]=in;
}
i++;
}
printf("Out of Loop");
My output when inputting 5 6 78 is:
assigning
space
assigning
space
assigning
assigning
assigning
With this output I doubt whether 78 is being stored in one memory location.
I would really appreciate your help,Thankyou
C++:
std::vector<int> v;
std::string s;
int i;
std::getline( std::cin, s); // read full line with whitespaces
std::istringstream iss( s); // prepare to process the line
while( iss >> i) v.push_back( i); // read into i and push into vector if
// operator>> was successful
C:
int array[ 10];
int i = 0, retval;
while( i < 10 && ( retval = scanf( "%d", &array[ i++])) == 1) ;
if( i == 10) {
// array full
}
if( retval == 0) {
// read value not an integer. matching failure
}
if( retval == EOF) {
// end of file reached or a read error occurred
}
You are deciding character by character. Thus, you will only store single digits or ignore those digits.
You could store the whole numbers like this (extending your code):
bool currentNumberStarted = false;
int currentNumber = 0;
int idx = 0;
while ((in=getchar()) != '0')// you probably want '\0' instead of '0'
{
if (in == ' ')
{
if (currentNumberStarted)
{
input[idx]=currentNumber;
idx++;
currentNumberStarted = false;
}
printf("space\n ");
continue;
}
else
{
printf("assigning\n ");
currentNumberStarted = true;
currentNumber *= 10;
currentNumber += in;
}
}
printf("Out of Loop");
First of all I highly doubt that your while loop will ever end, even if you made that to '\0' ,Because you are using char variable to store input. Not strings, Only strings uses '\0' at the end,How can we enter '\0' from keyboard..???. even if you want to keep it as '0',you would alwasy have to enter 0 as last number to end the loop(which i think you dont want to.)
So the Solution is this:-
After Entering Numbers You will Hit ENTER key, which would generate a newline character '\n' so you have to check for new line character('\n'), And as you are using getchar() function, it will returns EOF (-1) at the end of input, so its important to check for it too.So you have to check for both '\n' and EOF at once in while loop.And at last you should also check for array index number(it should be less than 1) in which you are storing numbers.
I made some effort to make you understand the program in comments.
int main()
{
int i=0;
int input[10]={0}; //here only 10 integers can be entered(hence i should be i<10)
int in; //To store input character
int num=0; //To store number which is converted from character.
int new=1; //To check if new number is started 0=false 1=True.
int count=0;//This is just to know how many numbers entered,also used to print numbers at end.
while ((in=getchar()) != '\n' && (in!=EOF) && i<10)//should check for both '\n' and EOF and array index also
{
if (in == ' ')
{
printf("space\n ");
if(new==0) //if new Number is not started yet.
{
new=1; //Start of a New number.(a number entered after space)
i++; //As new number is started it should be stored in new array index.
}
continue; //if space is entered just go to begining
}
else
{
printf("assigning\n ");
num=in-48; //converts a character to number (ex:- converts '3' to 3)
input[i]=(input[i]*10)+num; //storing the number..This is important do a paper work to understand this step.
new=0; //still in same number(we are still processing same number)
}
}
printf("Out of Loop \n");
count=i+1; //This gives correct count of numbers entered
for(i=0;i<count;i++) //to print numbers.
printf("%d ",input[i]);
return 0;
}
OUTPUT:-
E:>example.exe
78 2 65 998 1
assigning
assigning
space
assigning
space
.
.
.
space
assigning
Out of Loop
78 2 65 998 1

how to read characters and integers from a file?

So I have a data file that looks something like this:
x + y + z
30 45 50
10 20 30
The only characters I needed was the operators, so '+' '+' I was able to use file.get() to successfully get those characters and put them in an array. Problem is I need to get the next line of numbers, and assign them to the values x , y z . I know I cant use .get() , I would have to use getline. Will i have to eliminate the file.get() and use getline instead for first part also?
I looked at some of the questions posted on here but none of them were quite like mines. Note I'm actually going to be using these values for another part of my program, just used cout to see if my values were being read correctly
Here's my previous code:
main(int argc, char *argv[])
{
int a=0;
int n;
fstream datafile;
char ch;
pid_t pid;
int a, b, c, result;
string line;
datafile.open("data1.txt");
if(datafile)
{
for(int i=0; i <9; i++)
{
datafile.get(ch);
if (ch == '*'||ch == '/'||ch == '+'||ch == '-')
{
operations[a] = ch;
cout<<operations[a];
a++;
}
}
}
else
cout<<"Error reading file";
}
So this is how I was getting the first line of the file in the beginning. It worked like I wanted it to, may have not been the nicest coding but it worked. Nevertheless I tried to get the rest of the file, this time using getline, but instead of getting the numbers I was getting a bunch of random gibberish/numbers. I know if I use getline, the first line cannot be in my loop. I know this is how I would get the numbers.
while(getline(datafile, line))
{
istringstream ss(line);
ss >> x >> y >> z;
cout<<x<<""<<y<<""<<z;
}
Would the following make sense for the first line, or am I missing something:
string input;
std::getline(datafile, input)
for (int i = 0; i < input.size(); i++)
if (input[i] == '+' || ...)
{
operations[a] = input[i];
a++;
}
If you don't want to use getline, you could simply read the entire file stream (note that the bool is a rather naive way to handle the problem, I'd recommend something more elegant in your actual code):
bool first = true;
string nums;
int lines = 0;
vector<vector<int>> numlines;
vector<int> topush;
while (!datafile.eof())
{
char ch = datafile.get()
if (ch == 12 && first) //I don't know if '\n' is valid, I'd assume it is but here's the sure bet
first = false;
else if (first && (ch == '+' || ...))
{
operator[a] = ch;
a++;
}
else if (!first && (ch >= '0' && ch <= '9'))
{
if (!(datafile.peek() >= '0' && datafile.peek() <= '0'))
{
numlines[lines].push_back(atoi(nums.c_str());
nums.clear();
if (datafile.peek() == 12)
{
numlines.push_back(topush);
lines++;
}
}
else
nums = nums + ch;
}
Honestly, I can't be sure the above will work exactly right, I'd recommend you just modify your code to use getline exclusively. You'll need to add #include to get atoi.
Add this to your code:
while(!datafile.eof()){
string s;
getline(datafile, s);
istringstream in(s);
string tmp;
while(in >> tmp){
int i = stoi(tmp)
//Do something with i....
}
}