Tim said:
I'm new to C++, and tried to start making a script that will shuffle an
array. Can someone please tell me what's wrong?
#include <iostream.h>
This is not a standard header. Standard C++ uses <iostream>. This
suggests that you are learning from a source that is either very
outdated, inaccurate, or (most likely) both.
This is standard said:
int main () {
srand(time(0));
Where did srand() and time() come from? You haven't #included the
appropriate headers for these. Those headers are <cstdlib> and <ctime>,
respectively. Alternatively, the old deprecated versions are <stdlib.h>
and <time.h>.
If you use the first, non-deprecated versions, the functions will be in
namespace std::, and you need to account for that. So, for example, you
could do this:
std::srand(std::time(0));
Note also, that seeding the random number generator isn't always a good
idea. You are debugging your program -- consistency is good during this
phase. If you don't seed the random number generator (or seed it with
some constant value, like 7), then you'll get the same sequence of
numbers on each run, which makes debugging much easier.
int array_length;
int count;
int randm;
char temp[30];
Consider using std::strings instead of char arrays. They are safer, more
flexible, easier, and less error-prone.
Don't declare everything up front. Declare things where you use them. It
makes the code more clear, and someone reading the code does not need to
search as much for the declaration of an object.
cout << "How many items in array? ";
cout, cin, etc. are all in namespace std::, and you need to account for
this somehow. So, for example, you could use this:
std::cout << "some output" << std::endl;
std::cin >> some_var;
What if this input operation fails? You should check for success. If it
fails, array_length will have an undefined value. Using it for anything
other than giving it a defined value would be bad.
char items [30][array_length + 1];
This is illegal. Your compiler should reject it. If it doesn't, check
the documentation about how to invoke it in standards-compliant mode.
The problem is that array sizes must be compile-time constants.
array_length + 1 is not known at compile-time.
You should also prefer standard containers to arrays. std::vector is
almost a drop-in replacement for arrays, and is more flexible and
potentially safer.
It appears that a good replacement for this would be
std::vector said:
for (count = 0; count <= array_length; count++) {
Not a major issue, but prefer pre-increment to post-increment when the
end result is the same. pre-inc may be faster, and is almost certainly
not slower, than post-inc. This probably makes no difference with
built-in types, but it's a good habit nonetheless.
if (count != 0) {
cout << "\nWhat shall item " << count << " be?\n\t";
}
cin.getline (items[count], 30);
This is wrong. What happens when 'count' is 500? The first index of
'items' only goes to 29, so you are potentially overflowing your array
bounds and invoking undefined behavior. Also, 30 may be more characters
than can fit in 'items[count]'. Basically, you reversed your indices in
the declaration (which, as I mentioned, was illegal anyway because one
of the sizes was not a compile-time constant).
After fixing all this, you still need special handling for when the line
is longer than your maximum string size.
If you used std::strings instead of char arrays, you could do this:
std::getline(items[count]);
Easier, safer, almost impossible to get wrong, not limited to some
arbitrary length.
}
for (count = 0; count < array_length; count++) {
randm = rand() % array_length;
For various reasons, this is a poor way to limit rand()'s range. The
comp.lang.c FAQ has information on this. But for simple cases, it rarely
matters much.
strcpy (temp[30], items[30][count]);
This is wrong. temp[30] doesn't exist, nor does
items[30][any_value_here]; Array bounds in C++ go from 0 to array_size-1.
Besides that, there is a type mismatch. strcpy() expects arguments of
type char* (const char* in the case of the source string), and you are
passing char. This is precisely what your error message says. You
probably wanted something like:
std::strcpy(temp, items[count]);
This assumes a few other changes in the code:
1) The std:: qualification assumes #include <cstring> instead of
#include <string.h>.
2) items[count] is only valid if you reverse the indices in the
declaration of items.
Better still, get rid of the arrays and use vectors and strings like
I've mentioned a few times:
std::string temp;
std::vector<std::string> items;
//...
// No need for special functions when dealing with
// std::string -- the normal operators work fine:
temp = vector[count];
//ERROR
strcpy (items[30][count], items[30][randm]); //ERROR
strcpy (items[30][randm], temp[30]); //ERROR
Same basic problems here.
Finally, the standard library provide the function std::random_shuffle()
that does what you want.
Can someone please tell me what is wrong? The errors I get are:
21: error: invalid conversion from 'char' to 'char*'
21: error: invalid conversion from 'char' to 'const char*'
The errors could hardly be more clear. The function you are calling
expects char* and const char* arguments, you passed char arguments.
-Kevin