The signature of your function is
void dataIn(int quantity, participants a[quantity])
At very first, C++ doesn't allow to use function parameters outside the function body, so this is the reason why it won't compile.
Apart from, this signature actually is equivalent to
void dataIn(int quantity, participants*)
// legal variant of, exactly equivalent(!),
// not re-using quantity parameter either (-> compiles):
void dataIn(int quantity, participants[])
Raw arrays are always passed to functions as pointer to their first element, we say: an array decays to a pointer. Note, though, that this doesn't apply for further dimensions, i. e.
void f(int[whatever][SomeCompileTimeConstant])
remains equivalent to
void f(int(*)[SomeCompileTimeConstant])
Back to the original function: Note that it accepts two parameters, so you need to pass two as well:
participants a[quantity];
dataIn(quantity, a);
// ^
Note the array decaying to pointer, as mentioned already!
Additionally be aware that above is invalid C++:
int main()
{
participants a[quantity];
}
You are defining a VLA (variable length array), but that is only valid in C, not in C++. However, as many C++ compilers can translate C as well, they provide VLA for C++ as an extension. And that's the problem, no guarantee that all compilers do so, so your code is not portable.
So if you need dynamically sized arrays, switch over to std::vector*:
void dataIn(size_t quantity, std::vector<participant>& v)`
Note that I changed type of quantity parameter as well: Appropriate type for passing array lengths is size_t, not int.
std::vector<participant> a;
a.reserve(quantity); // optimisation: prevents re-allocations
dataIn(quantity, participants);
Actually, with std::vector you can have a much cleaner interface:
std::vector<participant> dataIn( )
// ^ no parameters needed at all!
{
ifstream in("...");
size_t quantity;
in >> quantity;
// TODO: check stream state, and possibly maximum for quantity (file validity!)
std::vector<participant> a;
a.reserve(quantity);
while(quantity--) { ... }
return a;
}
As you see, all relevant file operations now are placed into one single function (dataIn) and not distributed all over your programme. Especially, the file stream itself is in scope of this function as well and will be closed automatically on leaving. Be aware that with return value optimisation, the vector will be immediately constructed at the target location, so there even isn't any copying or moving involved...
* Even if you need fixed size arrays, std::array is a more modern and better alternative, it just wraps around a raw array, but behaves like any other ordinary object, so nothing of all that decaying to pointer stuff, additionally it comes with a more elaborate interface, e. g. a size() member, so no need to rely on the 'good old' sizeof(array)/sizeof(*array) trick either.