Reputation: 67
I basically want to store a array of student names, based on a given number. For example, if the user wants to insert 5 names, then the array size will be 5. If the user wants to insert 10 names, then the array size will be 10.
I have a method like this to set a name to a specific element in an array.
void setNames(char *names){
strcpy(name[i], names);
}
Thing is, how do I do array bound checks? I heard that you can only add when the index is -1
.
Upvotes: 1
Views: 172
Reputation: 446
When programming in C/C++ (unless using C++11 or newer), you will manipulate arrays as pointers. That means you won't know the size of an array unless you save it. What char str[10]
really means is str's address + 10 * sizeof(char)
. You are directly dealing with memory here.
If you want a high level approach for that, take a look at C++11. std::array
and std::vector
are there for you. From the documentation, look how std::array
is defined:
template <
class T,
std::size_t N
> struct array;
It means it stores its own size and has useful functions as well, such as size()
, at()
, back()
etc.
Upvotes: 0
Reputation: 154592
C code needs to keep track of the array size in another variable.
typedef struct {
char **name;
size_t n;
} Names_T;
void Names_Set(Names_T *names, size_t index, const char *name) {
// See if it is a special value and then append to the array
if (index == (size_t) -1) {
index = names->n;
}
if (index >= names->n) {
size_t newsize = index + 1;
// OOM error handling omitted
names->name = realloc(names->name, newsize * sizeof *names->name);
while (names->n < newsize) {
names->name[names->n++] = NULL;
}
}
char *oldname = names->name[index];
names->name[index] = strdup(name);
free(oldname);
}
void Names_Delete(Names_T *names) {
while (names->n > 0) {
names->n--;
free(&names->name[names->n]);
names->name[names->n] = NULL;
}
free(names->name);
names->name = NULL;
}
int main(void) {
Names_T names = { NULL, 0 };
Names_Set(&names, 3, "Sam"); // set array element 3
Names_Set(&names, (size_t) -1, "Thers"); // Append to array
Names_Delete(&names);
return 0;
}
Upvotes: 0
Reputation: 24354
EDIT (as the OP indicated he actually wants C):
C answer
What you can do is either create a char
array:
char [N][name_length]
where N - number "user wants" (I assume the user will somehow input it into your program), name_length - maximum length the name can have (a C-string, i.e. null-terminated string).
or create an array of your own struct
s (each holding a separate name and maybe some other information).
C++ answer
A typical way to do this in C++ is by using std::vector<std::string>
(assuming you only want to store names, as std::string
).
You then add new elements using using push_back()
function. And, as vector is implemented as a dynamic array in C++, you won't have to do bound checking.
Upvotes: 1
Reputation: 3484
Arrays don't maintain their own size, you have to do that for them. This is part of the reason why vectors are so much easier to deal with, and why everyone will say "wtf, raw arrays? use a vector". An array is just a contiguous chunk of memory, thats it. a vector contains an array, and lets you use it like an array to some extent, but it handles a lot of the housekeeping details for you.
Anyway, if you really want to use a raw array, then you'll need to pass around size information along with it. C strings are a null-terminated array -- just a plain old array, but the last element is \0
. This way you can read from it without knowing it's size ahead of time, just don't read past the null character at the end (dragons be there).
Upvotes: 1