Size of char array decided by user input?

I want to declare a char array with not initial size. Later I will prompt the user to enter in a sentence. This input will be stored in the char array using getline.

But how do I make the number or chars entered by the user to become the size of the char array?

1
2
3
4
    char text[] = {}; // empty char array
    cout << "Please enter a sentence: << flush; // prompts the user

    cin.getline(text, ???); // Stores the input in the array.  


Line 4 is where the problem is. I dont want to put a specific number for the array size. I want the array size to be however many chars the user input was. The getline function, however, requires a specific number for the size of the array.

How do I get around this?

Last edited on
How do I get around this?
Use dinamically growing containers. Like std::string
1
2
std::string text;
std::getline(std::cin, text);
No, I need to use a char array. Not string.

Im actually trying to reverse a string using pointers, and the way I can to do that is to store it in a char array.
So, do as string does internally: dynamically allocate your array, then manually read string character by character. As soon you reach the end of the array, reallocate it to have more space, continue reading until you reach end of string.

Alternatively read line into std::string and use it internal buffer (create a pointers to it).
1
2
3
4
std::string line;
std::getline(std::cin, line);
char* text = &line[0];
int size = line.size();
Im not sure if Im allocating memory correctly in the program below. This is a new topic for me, so can you walk me through what Im doing wrong here?

The program asks the user to enter a string and then prints out the string reversed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <string>


using namespace std;


int main()
{
    char * ptr = new char [100]; // allocates an array of size 100
    cout << "Enter a string: " << flush;
    string str;
    getline(cin, str);

    for(int i = 0; i<str.length(); i++) // not sure if Im doing this part correctly
    {
        ptr[i] = str[i];                
    }

    char * pStart, * pEnd;

    int nChars = sizeof(ptr)-1;

    pStart = ptr; // points to start of string

    pEnd = ptr + nChars - 1; // points to end of string

    while(pStart < pEnd) // reverses string
    {
        char temp = *pStart;
        *pStart = *pEnd;
        *pEnd = temp;

        pStart++;
        pEnd--;
    }

    cout << ptr << endl; // prints out the reversed string

    delete [] ptr;
    ptr = 0;

   cin.get();

}
Last edited on
// not sure if Im doing this part correctly
It is fine, but you forgot trailing 0 at the end.
int nChars = sizeof(ptr)-1;
Invalid. Always will be either 3 or 7. Use strlen here.

cout << "Enter a string: " << flush;
Flush is not needed here.

Invalid. Always will be either 3 or 7. Use strlen here.


There we go! Its working ALMOST perfectly now. Only problem is, I sometimes get a garbage character at the end of the string. It usually happened when I enter a short string. A full sentence seems to be working fine. Any idea whats going on here?

What do you mean by trailing 0?

Thank you for being patient with me.
Probably because of what MiiNiPaa said, the trailing 0.

Strings are zero terminated, a way to know the end of the string has been found. That rubbish value is a non 0 byte in the char array.

Easy fix should be, put a 0 at the element equal to the string size.
Still not understanding...

Sorry, are we talking about the null terminating character at the end of a string here?

What do you mean by:
put a 0 at the element equal to the string size.
?
Last edited on
Its working ALMOST perfectly now.

Could you post the latest version of your code (but leave the copy above as-is so we have something to compare it with.)

Andy

PS Earlier on said "No, I need to use a char array. Not string." Is this part of the overall problem statement?
Last edited on
PS Earlier on said "No, I need to use a char array. Not string." Is this part of the overall problem statement?


That was just a restriction I put on myself. I guess im violating it now as im using both string and char, but that's alright.


Anyway, here is my latest code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <string>


using namespace std;


int main()
{
    char * ptr = new char [100]; // allocates an array of size 100
    cout << "Enter a string: " << flush;
    string str;
    getline(cin, str);

    for(int i = 0; i<str.length(); i++) // puts each character of string into pointer array
    {
        ptr[i] = str[i];
    }

    char * pStart, * pEnd;   // delcare two char pointer


    int nChars = str.length();   // number of character in string entered

    pStart = ptr; // points to start of string

    pEnd = ptr + nChars-1; // points to end of string

    while(pStart < pEnd) // reverses string
    {
        char temp = *pStart;
        *pStart = *pEnd;
        *pEnd = temp;

        pStart++;
        pEnd--;
    }

    cout << ptr << endl; // prints out the reversed string

    delete [] ptr;        // de-allocates memory
    ptr = 0;

   cin.get();

}



As I said before, im getting a garbage character when I input a string of 6 or 4 characters.
Think about how you would say that something is the last character in the string if you would iterate over memory character by character.

Ant then read article on c-string structure. http://www.cplusplus.com/faq/sequences/strings/c-strings-and-pointers/

I got it!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>

using namespace std;

int main()
{
    char * ptr = new char [100]; // allocates an array of size 100
    cout << "Enter a string: " << flush;
    string str;
    getline(cin, str);

    for(int i = 0; i<str.length(); i++) // puts each character of string into pointer array
    {
        ptr[i] = str[i];
    }

    char * pStart, * pEnd;   // delcare two char pointers


    int nChars = str.length();   // number of character in string entered

    pStart = ptr; // points to start of string

    pEnd = ptr + nChars-1; // points to end of string

    while(pStart < pEnd) // reverses string
    {
        char temp = *pStart;
        *pStart = *pEnd;
        *pEnd = temp;

        pStart++;
        pEnd--;
    }

    for (int i=0; i<str.length(); i++) // loops up to the last element before null terminator
    {
        cout << ptr[i] << flush; // prints out the reversed string
    }

    delete [] ptr;
    ptr = 0;

   cin.get();

}


Many thanks to MiiNiPaa who was patient with me throughout this thread. I could not have done this without your help my friend. Thank you.

Thanks to the others as well.
Last edited on
Well, you just hid the problem that ptr is not a proper c-string. Still it works.

Proper way would be just to add null terminator at the end:
1
2
3
ptr[nChars] = '\0';
//...
std::cout << prt << '\n';
I think it's confusing things a bit by using std::string in tandem with a char buffer.

1. Just the char buffer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
//#include <string>
#include <cstring>

using namespace std;

int main()
{
    // NOTE 100 is not really worth using the heap for; would be better to use
    // a stack variable for the buffer (it's pretty routine to use char buffers
    // of size 1024 for Windows applications, though this might be an issue when
    // working with embedded devices and the like)
    //
    // and 100 is a bit tichy!
    //
    //char * ptr = new char [100]; // allocates an array of size 100
    const int buffer_size = 100;
    char * ptr = new char [buffer_size]; // allocates an array of size 100
    //cout << "Enter a string: " << flush;
    cout << "Enter a string: "; // no need for flush
    //string str;
    //getline(cin, str);
    cin.getline(ptr, buffer_size); // use getline method which works with char buffers

    //for(int i = 0; i<str.length(); i++) // puts each character of string into pointer array
    //{
    //    ptr[i] = str[i];
    //}

    //char * pStart, * pEnd;   // delcare two char pointers

    int nChars = strlen(ptr);   // number of character in string entered

    //pStart = ptr; // points to start of string
    char * pStart = ptr; // points to start of string

    //pEnd = ptr + nChars-1; // points to end of string
    char * pEnd = ptr + nChars-1; // points to end of string

    while(pStart < pEnd) // reverses string
    {
        char temp = *pStart;
        *pStart = *pEnd;
        *pEnd = temp;

        pStart++;
        pEnd--;
    }

    // print out string char by char...
    //for (int i=0; i<str.length(); i++) // loops up to the last element before null terminator
    for (int i=0; i<nChars; i++) // loops up to the last element before null terminator
    {
        //cout << ptr[i] << flush; // prints out the reversed string
        cout << ptr[i]; // prints out the reversed string (no need for flush)
    }
    cout << "\n"; // plus add endline

    // print out string again!!
    cout << ptr << "\n";

    delete [] ptr;
    ptr = 0;

    cin.get();
}


Tidied up...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    const int buffer_size = 256;
    char buffer[buffer_size];

    cout << "Enter a string: ";
    cin.getline(buffer, buffer_size);

    int nChars = strlen(buffer);

    char * pStart = buffer; // points to start of string
    char * pEnd = buffer + nChars - 1; // points to end of string

    while(pStart < pEnd) // reverse string
    {
        char temp = *pStart;
        *pStart = *pEnd;
        *pEnd = temp;

        pStart++;
        pEnd--;
    }

    // print out string char by char...
    for (int i=0; i<nChars; i++)
    {
        cout << buffer[i];
    }
    cout << "\n";

    // print out string again!!
    cout << buffer << "\n";

    cin.get();
}


Andy
Last edited on
2. Just the string (using index-based instead or iterator-based access)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <string>

using namespace std;

int main()
{
    cout << "Enter a string: " << flush;
    string str;
    getline(cin, str);

    int nChars = str.length(); // number of character in string entered

    int start = 0; // index of start of string

    int end = nChars - 1; // index of end of string

    while(start < end) // reverses string
    {
        char temp = str[start];
        str[start] = str[end];
        str[end] = temp;

        start++;
        end--;
    }

    for (int i=0; i<str.length(); i++)
    {
        cout << str[i];
    }
    cout << "\n";

    cout << str << "\n";

    cin.get();
}
Topic archived. No new replies allowed.