1

I have to initialize an array of string pointers to point to 4 worker names. Then i want to call a function func1() which prints out all the names. And i have to do this using either pass by referebce or values or may be a hybrid of these, anything is fine.

I have already been through following queries of similar type

how to initialize string pointer?

c++ initialization of an array of string pointers

returning array of string from function not working as expected

Also tried to use the Books Deitel and deitel and C++ Primer yet, could not understand or clarify my understanding regarding array of string pointers, to a point that now i am even getting confused with the fundamental basics of this.

Although, having gone through numerous similar questions online i could get only this far, as per the code I have written below.

My Code:-

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

void func1(string *str, int *num)
{
    for (int i = 0; i <= (*num); i++)
    {
        cout<<"\n"<<str[i]<<"\n";
    }
    cout<<"reached to the end of calling function\n\n";
}

int main() 
{
    int num; 
    cout<<"\nplease input your prefered size of array\n";
    cin >> num;  // Number of  names elements
    cout<<"\nplz enter the desired names\n";
    string *str = new string[num];
    for (int i=0;i<num;i++)
    {
        getline(cin, str[i]);
    }

    cout<<"now printing all the names through a calling function\nusing appropriate parameters\n";

    func1(str, &num);

    return 0;
}

Present Behaviour:-

Code executes and takes the input from me, but as soon as i give the second-to-the-last value, it gives a prompt error saying "file1.exe has stopped working". However, it does carry on with the remaining task and calls func1() and prints the ending line of the called function.

Output:

please input your prefered size of array

4

plz enter the desired names

Pratik

Pratik Vyas

Pratik Vyas A

now printing all the names through a calling function using appropriate parameters

Pratik

Pratik Vyas

Pratik Vyas A


Process exited after 14.24 seconds with return value 255 Press any key to continue . . .



And i have to close the terminal due to the prompt error that i get as soon as i have entered the third name Pratik Vyas A as described above.

I understand that this may be some really basic level issue, but only if my brain could process other numerous ways given online, that i would have saved this question space for some other worthy important questions. any help appriciated highly.

Community
  • 1
  • 1
Code Man
  • 105
  • 1
  • 2
  • 14
  • 2
    Why are you passing `num` by pointer? – Jonathan Wakely Oct 15 '15 at 19:05
  • 2
    If you didnt come across `std::string` and `std::vector` you are reading the wrong books ;) – 463035818_is_not_an_ai Oct 15 '15 at 19:05
  • @tobi303 i did come accross those but i also came accross the fact that if i use "using namespace std;" statement, i may generally not have to use std:: scope everytime. so i went ahead with my narrow thinking i believe. – Code Man Oct 15 '15 at 19:08
  • @JonathanWakely i thought i am passing the num by a reference in the function call isnt it? – Code Man Oct 15 '15 at 19:09
  • 1
    @CodeMan but why? why not just pass an `int` by value? – Jonathan Wakely Oct 15 '15 at 19:10
  • 1
    You have code that reads a number, but what you want is to read a line. – David Schwartz Oct 15 '15 at 19:11
  • @JonathanWakely yes. makes a point. trying it now – Code Man Oct 15 '15 at 19:12
  • 2
    `func1`'s `for` loop goes to `<= num`, which is one past the end of the array. – crashmstr Oct 15 '15 at 19:20
  • @crashmstr Wholly Chao, yes that worked......i cant believe none of these answers below worked and i failed to see that i had defined two different kinds of ranges for the for loops on the same data set using reference to the memory locations. omg...Thanks a ton. i will soon answer my own question with this solution and put ur reference in......GR8 GRATITUDE to you. – Code Man Oct 15 '15 at 20:02

4 Answers4

2

If you add the line

cin.ignore();

before reading input, this won't happen.

The source of the problem is that when you read input with cin like

cin >> num;

cin reads up to the newline character, and stops there (before the newline, leaving the newline in the buffer). When you call getline, the first thing it sees is the \n left in the buffer from when the user entered a number, so you get an empty string in the first element of your array. Notice how your code left a gap of three lines before printing the names, when you only told it to leave one line - it's because the middle of those lines was the (empty) first string.

Here's the main method with that change made, I've tested this code on my computer and it works correctly:

int main()
{
    int num;
    cout<<"\nplease input your prefered size of array\n";
    cin >> num;  // Number of  names elements
    cout<<"\nplz enter the desired names\n";
    string *str = new string[num];
    cin.ignore();
    for (int i=0;i<num;i++)
    {
        getline(cin, str[i]);
    }

    cout<<"now printing all the names through a calling function\nusing appropriate parameters\n";

    func1(str, &num);

    return 0;
}
Chris H
  • 790
  • 9
  • 19
  • OHH!!!........thats a new learning for me regarding redundant use of my newline character. I do that on the greed of neatness but now i see how it messes up.....Thanx so much am trying it now – Code Man Oct 15 '15 at 19:14
  • 1
    sorry, maybe that was unclear - the newline character that's left in the stream is *not* the newline character from your print statement, it's the newline character from when the user enters the number. This is just a quirk of how `cin` and `getline()` work. – Chris H Oct 15 '15 at 19:18
  • nope it didnt work i tried getting rid of the newline character from allost all possible places surrounding the statement of reading num.........there is still an error when i run the program. a prompt error. – Code Man Oct 15 '15 at 19:40
  • 1
    Read my edited post - you don't need to remove any newline characters from your code. If you go back to what you posted in the question, but just add the line `cin.ignore();` before starting the loop to get inputs (I'll add the whole section into my answer, for clarity), it works. – Chris H Oct 15 '15 at 19:43
  • ok trying before loop now.....i was trying it before the cin>>num i thought dats wat ya meant.......but now m trying before the loop begins. – Code Man Oct 15 '15 at 19:49
  • btw @crashmstr solution worked............pinpoint.........i always wondered as to why is it behaving in an out of bounds/range way – Code Man Oct 15 '15 at 19:51
  • hey i dont mean to bug you here, but even that didnt work even before loop.........but it makes sense now that i was giving different range to the for loop in the function definition as compared to the main fuction reading input and hence that is where the new empty line string comes from. yup i think that should be the reason why it gave me garbages occasionally on certain other edits to my code.... BTW Chris, u have been a really helpfulll one for this query really appreciate ur responses to my redundance. – Code Man Oct 15 '15 at 19:56
  • 1
    Yes, the change to the loop condition is also important to avoid going out of bounds on your array. That, combined with the version of the `main` function in my answer now, should have your program working completely as desired. – Chris H Oct 15 '15 at 20:19
1

After you read the number into num the newline that followed it is still in the stream, so the first iteration of the loop reads an empty string.

You could debug this for yourself by changing the loop to show you what it's doing:

for (int i=0;i<num;i++)
{
    if (getline(cin, str[i]))
      cout << "got: " << str[i] << std::endl;
    else
      cerr << "Failed to read!\n";
}

You should learn to debug your own code like this, to find out what it's really doing, instead of just asking here.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • agreed, i am new to the debugging feature and honestly havent been using it much only due to the fear that i may get distracted into another doubt that i may not understand in turn. – Code Man Oct 15 '15 at 19:11
  • it didnt work, i tried to remove newline and use getline too but didnt work. – Code Man Oct 15 '15 at 19:41
0

Use vector and string:

typedef std::vector<std::string> stringVec;

void foo(const stringVec& names){
    for (int i=0;i<names.size();i++){std::cout << names[i] << std::endl;}
}

int main(){
    stringVec s;
    s.push_back("Peter");
    s.push_back("Klaus");
    foo(s);
}

... and dont use using namespace std; (cant find the link but I will look for it)

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • 1
    here is the link for explaining [why is using namespace std considered bad practic](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – 463035818_is_not_an_ai Oct 15 '15 at 19:13
  • Thanks now i see....yep......although on your answer, i am supposed to do it without vectors or templates, nor am i any good with those features. – Code Man Oct 15 '15 at 19:17
0

From the comments of posted in response to the question, one particular comment identifies a main, fundamental and clear flaw in the code design, which when rectified, the code functions right on target fulfilling the main purpose. Responded by @crashmstr

"func1's for loop goes to <= num, which is one past the end of the array."-crashmster

,hence exhibiting an 'out of bounds' or 'out of range' kind of behaviour in most compilers (generally all), with some compilers, while still giving the final output on screen alongside of the prompt-box error, for eg:- codeblocks, devcpp, codebox, scripter etc. gratitude.

below is small but specific correction in the code

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

void func1(string *str, int *num)
{
    for (int i = 0; i < (*num); i++)
    {
        cout<<"\n"<<str[i]<<"\n";
    }
    cout<<"reached to the end of calling function\n\n";
}

int main() 
{
    int num; 
    cout<<"\nplease input your prefered size of array\n";
    cin >> num;  // Number of  names elements
    cout<<"\nplz enter the desired names\n";
    string *str = new string[num];
    cin.ignore();   //important input by @Chris Hengler as it controls
                    // aspects of out of bounds behaviour prevention
    for (int i=0;i < num;i++)
    {
        getline(cin, str[i]);
    }

    cout<<"now printing all the names through a calling function\nusing appropriate parameters\n";

    func1(str, &num);

    return 0;
}

now works fine. grats to Chris and Crash for responses.

Code Man
  • 105
  • 1
  • 2
  • 14