-3

For a project in my Intro to c++ class we are using char arrays of size 140 initialized with the following function:

void InputText(char A[140], string prompt)
{
    cout << prompt;
    cin.ignore();
    cin.getline(A,140);
}

I made this function to count the number of filled elements in an array:

int numElements(char A[140]) //searches for the first '\0' in an array and returns the index, if        none are found, returns 140
{
    int numEl = 140;
    for (int i = 0; i <= 140; i++) { if (A[i] == '\0') { numEl = i; break; } } 
    return numEl;
}

It works fine when I use it on arrays filled with InputText(), but when I tested it with another array like this:

char A[] = {'1', '2', '3', '4', '5'};
cout << numElements(A);

It will print out 13 instead of 5. I don't understand why this is happening.

  • 2
    `char A[] = {'1', '2', '3', '4', '5'};` is not a 0-terminated string literal. Try `char A[] = "12345";` instead. – The Paramagnetic Croissant Oct 24 '14 at 22:47
  • 1
    FYI you cannot do `for (int i = 0; i <= 140; i++)` because the valid indexes for a 140 element array are `0` to `139` so you should only iterate through for `(int i = 0; i < 140; i++)` – Cory Kramer Oct 24 '14 at 22:48
  • For C-Style arrays to get the size you can do `sizeof(A)/sizeof(A[0]);` – Ryan Oct 24 '14 at 22:50
  • I really wish intro to C++ classes would teach raw arrays in a useful context. This kind of stuff is why `std::string` was created, and intro classes should really be teaching you *useful* stuff, not misleading you into thinking character arrays are the way to go for strings in C++. – cdhowie Oct 24 '14 at 22:55
  • 2
    Assigning the values like this does not put a string termination character at the end as the first commenter said. It is just an array of characters. Try not to use magic numbers in your methods (eg 140) but check for the available array positions on the fly. Finally, remember that arrays in c++ are passed by reference, not by value, so be careful what you are passing. – DrinkBird Oct 24 '14 at 22:56
  • Thanks for the help guys, I figured it out. And yea cdhowie I hate how they teach it too. I'm going through the Bjarne Stroustrup intro text and he just keeps going on about how much more useful vectors are than arrays and yet we still have to do it this way. – Santiago Soto Oct 24 '14 at 23:01
  • 2
    @self: `sizeof(A)/sizeof(A[0]);` will not work in OP function, as the array are in fact pointers and not references to array. – Jarod42 Oct 24 '14 at 23:08

2 Answers2

0

The a array is not null terminated and that leads to undefined behavior. In your case it printed 13.
It could print out something else or even crash with an access violation.

You should add the '\0' as the last char in your array A to terminate the string so you will know where the end of the array data is like in your if statement A[i]=='\0'

Also (not directly connected to your question) your 'for statement' is wrong

your i runs from 0 to 140 (including 140 ) so it runs 141 times which is 1 more than your max value

you should use

i<140 instead of i<=140

Coldsteel48
  • 3,482
  • 4
  • 26
  • 43
0

The following void InputText(char A[140], string prompt) is in fact

void InputText(char* A, std::string prompt)

You may pass array by reference that way:

void InputText(char (&A)[140], std::string prompt)
{
    cout << prompt;
    cin.ignore();
    cin.getline(A, 140);
}

and similarly

int numElements(char (&A)[140]) {
    int numEl = 140;
    for (int i = 0; i < 140; i++) { if (A[i] == '\0') { numEl = i; break; } } 
    return numEl;
}

And declare it like

char A[140] = {'1', '2', '3', '4', '5'};
std::cout << numElements(A);

Note that in numElements, you acceded A[140] which is undefined behavior.

Jarod42
  • 203,559
  • 14
  • 181
  • 302