Size of char array decided by user input?

Jun 28, 2015 at 5:20am
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 Jun 28, 2015 at 5:26am
Jun 28, 2015 at 6:54am
How do I get around this?
Use dinamically growing containers. Like std::string
1
2
std::string text;
std::getline(std::cin, text);
Jun 28, 2015 at 9:45am
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.
Jun 28, 2015 at 9:53am
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();
Jul 3, 2015 at 8:18pm
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 Jul 3, 2015 at 8:18pm
Jul 3, 2015 at 8:24pm
// 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.

Jul 4, 2015 at 12:25am
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.
Jul 4, 2015 at 1:53am
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.
Jul 9, 2015 at 4:39am
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 Jul 9, 2015 at 4:39am
Jul 9, 2015 at 9:41am
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 Jul 9, 2015 at 9:43am
Jul 9, 2015 at 8:29pm
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.
Jul 9, 2015 at 8:33pm
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/

Jul 10, 2015 at 10:10am
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 Jul 10, 2015 at 10:10am
Jul 10, 2015 at 10:13am
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';
Jul 10, 2015 at 3:10pm
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 Jul 10, 2015 at 3:16pm
Jul 10, 2015 at 3:23pm
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.