Yes, there is a solution. Don't use non-standard VLAs and don't use Plain-Old Arrays that provide no bounds checking. The solution is to use a vector of strings, e.g. std::vector<std::string>
. That way you can add or replace any element you like and the memory is handled automatically.
For example, let's just take a vector of strings initialized with four strings:
std::vector<std::string> student { "my", "dog", "has", "fleas" };
Now student.size()
will tell you how many strings are contained in the vector and you can replace (with bounds checking) with student.at(pos) = "new string";
You can list all elements in your vector using a range-based for
loop, e.g.
std::cout << "Array:\n\n";
for (const auto& s : student)
std::cout << s << '\n';
Since the vector of strings student
contains all the information you will need to either replace an existing element or add a new element at the end, your function (which must be of a type to indicate success/failure of the operation) could be written to take a single parameter -- a reference to your vector of strings, e.g.:
bool st_insert(std::vector<std::string>& demo)
{
size_t pos;
std::string item {};
std::cout << "Enter a position number to insert: ";
if (!(std::cin >> pos))
return false;
std::cout << "Enter a new Element: ";
if (!(std::cin >> item))
return false;
if (pos >= demo.size())
demo.push_back(item);
else
demo.at(pos) = item;
std::cout << "\nAfter Inserting \""<< item <<"\", the updated list is:\n\n";
for (const auto& s : demo)
std::cout << s << '\n';
return true;
}
If you want a compilable example, with 0
-exit or 1
-st_insert as your menu choices, you could do:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
bool st_insert(std::vector<std::string>& demo)
{
size_t pos;
std::string item {};
std::cout << "Enter a position number to insert: ";
if (!(std::cin >> pos))
return false;
std::cout << "Enter a new Element: ";
if (!(std::cin >> item))
return false;
if (pos >= demo.size())
demo.push_back(item);
else
demo.at(pos) = item;
std::cout << "\nAfter Inserting \""<< item <<"\", the updated list is:\n\n";
for (const auto& s : demo)
std::cout << s << '\n';
return true;
}
int main (void)
{
int choice;
std::string tmp;
std::vector<std::string> student { "my", "dog", "has", "fleas" };
std::cout << "Array:\n\n";
for (const auto& s : student)
std::cout << s << '\n';
std:: cout << "\nEnter menu choice: ";
if (!(std::cin >> choice)) {
std::cerr << "error: invalid integer value - choice.\n";
return 1;
}
switch(choice)
{
case 0:
exit(0);
break;
case 1:
if (!st_insert (student))
std::cerr << "error: unable to insert element.\n";
break;
default:
std::cout << "Wrong choice please try again !!!\n";
}
return 0;
}
Example Use/Output
Replace Exmaple:
$ ./bin/insert_str_item
Array:
my
dog
has
fleas
Enter menu choice: 1
Enter a position number to insert: 1
Enter a new Element: cat
After Inserting "cat", the updated list is:
my
cat
has
fleas
Add Example:
$ ./bin/insert_str_item
Array:
my
dog
has
fleas
Enter menu choice: 1
Enter a position number to insert: 40
Enter a new Element: now
After Inserting "now", the updated list is:
my
dog
has
fleas
now
(note: the st_insert()
function was written so if the requested pos
for the new string exceeds what the next string in the vector would be, it is simply added as the next string and the invalid position is discarded)
Now when you go to take input for your vector of strings, it is quite simple. just read your input into a temporary string and use the .push_back()
member function to add the string to your vector of strings, e.g.
std::string tmp {};
std::cout << "enter a string: ";
if (std::cin >> tmp)
student.push_back(tmp);
(note: you must validate every user input before you use the value)
Adding Taking siz
New Elements
From your example, if you did want to specify the number of new strings to enter, you could adjust the program as follows:
int main (void)
{
int choice;
size_t siz;
std::string tmp;
std::vector<std::string> student { "my", "dog", "has", "fleas" };
std::cout << "There are currently " << student.size() << " elements:\n\n";
for (const auto& s : student)
std::cout << s << '\n';
std::cout << "\nHow many elements would you like to add? ";
if (!(std::cin >> siz)) {
std::cerr << "error: invalid size-type input.\n";
return 1;
}
for (size_t i = 0; i < siz; i++) {
std::cout << "student[" << student.size() << "]: ";
if (std::cin >> tmp)
student.push_back(tmp);
}
std::cout << "\nCurrent strings:\n\n";
for (const auto& s : student)
std::cout << s << '\n';
std:: cout << "\nEnter menu choice: ";
if (!(std::cin >> choice)) {
std::cerr << "error: invalid integer value - choice.\n";
return 1;
}
switch(choice)
{
case 0:
exit(0);
break;
case 1:
if (!st_insert (student))
std::cerr << "error: unable to insert element.\n";
break;
default:
std::cout << "Wrong choice please try again !!!\n";
}
return 0;
}
Example Use/Output
$ ./bin/insert_str_item
There are currently 4 elements:
my
dog
has
fleas
How many elements would you like to add? 4
student[4]: my
student[5]: cat
student[6]: has
student[7]: none
Current strings:
my
dog
has
fleas
my
cat
has
none
Enter menu choice: 1
Enter a position number to insert: 5
Enter a new Element: frog
After Inserting "frog", the updated list is:
my
dog
has
fleas
my
frog
has
none
You will want to see std::vector and std::basic::string for full details of the use of std::vector
and std::string
. Also see: Why is “using namespace std;” considered bad practice? and C++: “std::endl” vs “\n”.
Look things over and let me know if you have further questions.