For goodness' sake, it's seems such a simple piece of code and I just can't figure out where I went wrong.
int count = 0;
for (int i = 0; i<10;i++){
if (chararray[i]=='\0' && i == 0){
cout << "Empty \n";
break;
}
if (chararray[i]!='\0') {
count = count ++;
}
}
cout << "Deleted " << count << "elements \n";
So the basic idea is that it goes through the array and if it's empty, then returns "Empty" and if not then it counts all the non empty cells and returns how many of them there were. If it makes any difference, I'm putting this under deconstructor method.
Generally it works fine, it just won't COUNT right. It either counts all or none.
UPDATE!
Thank you all! I removed the count = count++ line with ++count and it displayed more correct results than before, but not for all test values (and I promise not to make this same mistake again). As it is, I took the advice to use strlen function as there isn't a specific need for a 0 in place of, well, nothing. Also it made the code much, much shorter. Thank you!
You titled your question as
count empty char cells c++
however as it is seen in the code snippet the count is increased when an element of the array is not equal to '\0'
if (chararray[i]!='\0') {
count = count ++;
}
So what is the empty char cell that you are going to count?
Take into acccount that this statement
count = count ++;
has undefined behaviour because applying the side effect of operaator ++ is not sequenced relative to the left operand assignment.
If the array contains a string and you want to know whether it is empty and how many characters in the string then you should use standard C function strlen
If the array does not contain a string and elements with value '\0' can be in any place of the array then that tp count non-zero elements you should use standard algorithm std::count_if
For example
#include <algorithm>
#include <functional>
//..
int n = std::count_if( chararray, chararray + 10,
std::bind2nd( std::not_equal_to<char>(), '\0' ) );
if (chararray[i]=='\0' && i == 0){
This line looks for a null value and then checks if it is at index 0
Try this:
if(chararray[i]==`\0`){
to break on the first null value and stop counting.
Also:
Please please please change this:
if (chararray[i]!='\0') {
count = count ++;
It is Undefined Behaviour (UB) and will very likely not be working as intended or break at some later point.
It should be:
if (chararray[i]!='\0') {
count ++;
Assuming chararray has type char [] you can simply use std::count
auto num_items = std::count( std::begin( chararray ),
std::end( chararray ),
'\0'
); // returns 0 or number of occurrence
One problem:
count = count ++;
is undefined behavior: it could result in something like...
tmp = count; // count == 0
count++;
count = tmp; // count == 0
or...
tmp = count; // count == 0
count = tmp;
count++; // count == 1
Try ++count; instead.
Related
I'm a beginner in C++ and programming itself actually. I just want to ask, What's the difference between these 2 examples. What is the difference between "len = strlen(str1)-1" and "i = strlen(str1)-1"
Top part of the code will be like this:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char str1[20],str2[20];
int c, i ,j, len;
cout<<"Enter a word: ";
cin.getline(str1, 20);
Example 1:
//reverse
for (i = strlen(str1)-1, j = 0; i >= 0; i--, j++){
str2[j] = str1[i];
}
//compare string
c = strcmp(str1, str2);
/*This does not work because the value of 'c' will be -1 if the input
is "lol" which is palindrome*/
and Example 2:
//reverse
len = strlen(str1)-1;
for (i = len, j = 0; i >= 0; i--, j++){
str2[j] = str1[i];
}
//compare string
c = strcmp(str1, str2);
/*This does work in other hand, because of the variable "len"*/
the rest of the code will be like this
if(c == 0){
cout<<"It is a Palindrome";
}
//if the value of C is !=0
else{
cout<<"It is not a Palindrome";
}
}
Why is that? Thanks in advance for those who will answer. :)
Both examples are same except first uses an extra variable len.
This code is actually reversing the string. If str1 contains "123" then str2 will contain "321".
Function strlen(str1) returns the length of str1 but in C++ index of Arrays start from 0 that is why the last element index will be one less than length, hence strlen(str1) - 1.
UPDATE
Even with updated information the answer to first question remains same that both examples are same in nature. Difference in results is a mare co-incident due to a reason explained below.
char str1[20],str2[20];
This code creates two array of 20 char but not initialized. This means the initial values can be random.
Now when you call cin.getline(str1, 20); it not only writes the string you entered but adds a terminating '\0' character at the end of it. Our reversing logic only reverse the string but does not insert terminating '\0' at the end of str2 which means str2 is much longer (until it finds a '\0') than str1. Due to this they never compare correctly.
A simple solution to this issue can be zero-filling the arrays before using them and in C++ there is a simple way to do that:
char str1[20] = { 0 }, str2[20] = { 0 };
It is always a good practice to zero-fill your arrays if you are going to use then as strings.
I'm trying to create a program which allows for a dynamically allocated array to store some integers, increase the maximum size if need be, and then display both the unsorted and sorted array in that order.
Link to my full code is at the bottom.
The first issue I have is the dynamically allocated array going haywire after the size needs to be increase the first time. The relevant code is below.
while (counter <= arraySize)
{
cout <<"Please enter an integer number. Use 999999 (six 9's) to stop\n";
if (counter == arraySize) //If the counter is equal to the size of the array
{ //the array must be resized
arraySize +=2;
int *temp = new int[arraySize];
for (counter = 0; counter < arraySize; counter++)
{
temp[counter] = arrayPtr[counter];
}
delete [] arrayPtr;
arrayPtr = temp;
counter ++; //the counter has to be reset to it's original position
} //which should be +1 of the end of the old array
cin >> arrayPtr[counter];
if (arrayPtr[counter] == sentinel)
{
cout << "Sentinel Value given, data entry ending.\n";
break;
}
counter ++;
}
This produces the unintended operation where instead of waiting for the sentinel value, it just begins to list the integers in memory past that point (because no bounds checking).
The next issue is that my sorting function refuses to run. I tried testing this on 5 values and the program just crashes upon reaching that particular part of code.
The function is called using
sorting (arrayPtr);
but the function itself looks like this:
void sorting (int *arr)
{
int count = 0, countTwo = 0, tempVal;
for (count = 0; arr[count] != 999999; count++) //I figured arr[count] != 999999 is easier and looks better
{ //A bunch of if statements
for (countTwo = 0; arr[countTwo] != 99999; countTwo++)
{
if (arr[countTwo] > arr[countTwo+1])
{
tempVal = arr[countTwo];
arr[countTwo] = arr[countTwo+1];
arr[countTwo+1] = tempVal;
}
}
}
}
Any help on this issue is appreciated.
Link to my source code:
http://www.mediafire.com/file/w08su2hap57fkwo/Lab1_2336.cpp
Due to community feedback, this link will remain active as long as possible.
The link below is to my corrected source code. It is annotated in order to better highlight the mistakes I made and the answers to fixing them.
http://www.mediafire.com/file/1z7hd4w8smnwn29/Lab1_2336_corrected.cpp
The first problem I can spot in your code is in the for loop where counter goes from 0 to arraySize-1, the last two iteration of the loop will access arrrayPtr out of bounds.
Next, at the end of the if (counter == arraySize) there is a counter++; This is not required since at this moment counter is already indexing the array out of bound.
Finally in your sorting function the inner loop looks for the wrong value (99999 instead of 999999), so it never stop and goes out of bounds. To prevent this kind of error, you should define your sentinel as a const in an unnamed namespace and use it through the code instead of typing 999999 (which is error prone...).
I have a for loop where I'm using the slide operator as I'm working with unsigned types. Essentially it boils down to
for (std::size_t i = 6; i --> 0;){
cout << i;
}
But it outputs the numbers from 5 to 0 inclusive and omits 6. Why?
Thank you very much for looking at this. I'm quite stuck.
This is a touchstone for
The fact that this so-called "operator" should be used with caution, if at all.
Changing the state of variables within the conditional check of a for loop ought to be done with extreme caution, if at all.
The largest output is 5 simply because i is decremented as a result of the conditional test which also decrements i. The conditional check is ran before program control enters the for loop body.
You really ought to rewrite the loop. Don't set the initial value of i to 7 as that's a dirty hack. Although --> is often used with while (and to emphasise, it's unlikely to win you many friends in your programming review), I've never seen it used with a for loop before.
--> is not a slide operator.
It is understood by the compiler as two different operators -- and >.
So your code look like this to the compiler:
for (std::size_t i = 6; (i--) > 0;){
cout << i;
}
Since the loop condition is checked before entering the loop's body i is decreased before the first execution of the loop's body, hence the produced sequence of numbers is 5 4 3 2 1 0.
For more details see this Stack Overflow question: What is the "-->" operator in C++?
After evaluating this condition in the for statement
i --> 0
i will be equal to 5. So the first iteration of the loop outputs
5
To achieve the effect you want rewrite the loop the following way
#include <iostream>
int main()
{
size_t i = 6;
do
{
std::cout << i;
} while ( i-- > 0 );
return 0;
}
The program output is
6543210
Another way is the following
#include <iostream>
int main()
{
for ( size_t i = 6; std::cout << i && i != 0; i-- )
{
//
}
return 0;
}
Of course you could write the loop like this
const size_t N = 6;
for ( size_t i = N + 1; i-- > 0; )
// ^^^^^^^
{
std::cout << i;
}
However in general this approach does not work when the initial value of i is equal to std::numeric_limits<size_t>::max() Because if to add 1 to this value you will get 0.
A general approach using a for loop can look the following way
#include <iostream>
int main()
{
const size_t N = 6;
for ( size_t i = N, j = N; j != 0; j = i-- )
{
std::cout << i;
}
return 0;
}
Its output is
6543210
I have a very simple for if loop which takes in an array (a vector of vectors) called data, reads the 0th element of EACH row (i.e. the data[i][0] elements), and outputs the 5th elements of THAT specific row IFF it satisfies the condition that the first element is equal to an integer pid (user defined earlier in the code.) If the row doesn't start with that element, i want it to output nothing.
Here is my code for this loop:
for(int i = 0; i < data.size(); i++) {
if(data[i][0] = pid) {
cout << data[i][5] << endl;
}
}
However, when I run the program, it outputs the 5th element of EVERY row, not just the ones that start with pid. AKA, c++ seems to be completely ignoring my if statement.
Does anyone have an answer to this?
Thank you in advance!
You need to use == instead of = inside the if condition:
if(data[i][0] == pid)
Otherwise you are just assigning the value of pid to the array element and this will be true if pid is not 0.
You are using assignment operator = instead of the comparison operator ==
if(data[i][0] = pid) {
^^^
As for me I would write these loops the following way
for ( size_t i = 0; i < data.size(); i++ )
{
if ( data[i][0] == pid && data[i].size() > 5 )
{
cout << data[i][5] << endl;
}
}
If I have a set in C++, and it contains numbers from 0 to n. I wish to find out the number that is missing from 1 to n and output that and if none of them is missing, then output the number (n+1).
For example, if the set contains, 0 1 2 3 4 5 6 7, then it should output 8
If it contains, 0 1 3 4 5 6, then it should output 2.
I made the following code for this, but it always seems to output 0. I dont know what is the problem.
set<int>::iterator i = myset.begin();
set<int>::iterator j = i++;
while (1)
{
if ( *(j) != *(i)+1 )
{
cout<<*(j)<<"\n";
break;
}
else
{
i++;
j++;
}
}
What is the problem? Thanks!
The problem is that you're advancing i:
set<int>::iterator i = myset.begin(); // <-- i points to first element
set<int>::iterator j = i++; // <-- j points to first element
// i points to second!
while (1)
{ // so if our set starts with {0, 1, ...}
if ( *(j) != *(i)+1 ) // then *j == 0, *i == 1, *i + 1 == 2, so this
// inequality holds
What you meant to do is have j be the next iterator after i:
std::set<int>::iterator i = myset.begin(), j = myset.begin();
std::advance(j, 1);
With C++11, there's also std::next():
auto i = myset.begin();
auto j = std::next(i, 1);
Or, alternatively, just reverse your construction:
std::set<int>::iterator j = myset.begin();
std::set<int>::iterator i = j++; // now i is the first element, j is the second
Or, lastly, you really only need one iterator:
int expected = 0;
for (std::set<int>::iterator it = myset.begin(); it != myset.end();
++it, ++expected)
{
if (*it != expected) {
std::cout << "Missing " << expected << std::endl;
break;
}
}
The easiest stuff: Use count() function of set to check whether an element is present in set or not.
The count() takes an integer argument: The number whose existence in the set is to be checked. If the element is present in set, count() returns a non zero value, else it returns 0.
For example:
#include <iostream>
#include <set>
using namespace std;
int main()
{
set<int> s;
//I insert 0 - 4 in the set.
for(int i=0;i < 5; ++i)
s.insert(i);
//Let 10 be the 'n'.
for(int i = 0; i < 10; ++i)
{
//If i is NOT present in the set, the below condition will be true.
if (!s.count(i))
cout<<i<<" is missing!\n";
}
}
One problem is that you access beyond the end of the set if the set is
dense, which is undefined behavior. Another is that you always output
an element in the set (*j, where j is an iterator into the set);
according to your description, what you want to output is a value which
isn't in the set.
There are a couple of ways of handling this. The simplest is probably
just to maintain a variable expected, initialized with 0 and
incremented each time. Something like the following.
int
firstAvailable( std::set<int> const& allocated )
{
int expected = 0;
for ( auto current = allocated.begin(), end = allocated.end();
current != end && *current == expected;
++ current ) {
++ expected;
}
return expected;
}
If you don't want to return 0 if the list isn't empty, but starts with
some other value, initialize expected with the first element of the
set (or with whatever you want to return if the set is empty).
EDIT:
Of course, other algorithms may be better. For this sort of thing, I usually use a bit map.
The problem with your original code has already been pointed out in the other answers. You're modifying i while assigning j. You can fix this by initializing the iterators as:
set<int>::iterator i = myset.begin();
set<int>::iterator j = i;
j++;
A more elegant solution is to take advantage of the fact that the sum of all values up to n is n * (n + 1) / 2. You can calculate the sum of the actual values, and subtract it from the full sum to obtain the missing value:
int findMissing(const std::set<int>& valSet) {
int valCount = valSet.size();
int allSum = (valCount * (valCount + 1)) >> 1;
int valSum = std::accumulate(valSet.begin(), valSet.end(), 0);
return allSum - valSum;
}
The big advantage of this approach is that it does not rely on using a container where iterators provide the values in sorted order. You can use the same solution e.g. on an unsorted std::vector.
One danger to look out for when using this approach is overflow. With 32-bit ints, it will overflow with approximately 2^16 values. It might actually still work if it overflows, particularly if you use unsigned instead of int, but I did not confirm that.
There's a similar approach that uses the XOR of all values instead of the sum, which does not have the problem with overflow.