C++ char pointer array - cannot access elements - c++

I am having some trouble storing some char pointers in my array
The method should take a char* array and and int pointer which is the size of the array. Then I loop and ask the user to enter the names. Then I want to print them; however it seems like there's nothing in my array.
Note I cannot use array notation for this assignment, I must use pointer notation to access the elements of the array.
void sort_name(char* name[], int* items)
{
//store the names
cout << "In function items is " << *items << endl;
for(int i=0; i<*items; i++)
{
string str;
cout << "Enter name #" << (i+1) << ": ";
getline(cin, str);
char* current = new char[str.size() + 1];
*(name + i) = current;
}
for(int i=0; i<*items; i++)
{
cout << *(name + i) << endl;
}
}

char* current = new char[str.size() + 1];
*(name + i) = current;
You are correctly allocating new memory for each of the array elements, but you never assign any value to them. Since this is homework, I won't say more.

You forgot to copy the string entered by the user to the array. There is no copy from str to current.

You need to actually copy the string, rather than just allocate space for a copy. Try this:
int length=str.copy(current,str.size(),0);
current[length]='\0';
just after you allocate the string. I.e., put the above code right after this line in your code:
char* current = new char[str.size() + 1];

If you want to do this way you need to copy the actual entry.
check strcpy or memcpy.

add the second line : (and #include "stdio.h")
char* current = new char[str.size() + 1];
strcpy(current , str.c_str());
(name + i) = current;
it should work.
You use "int* items", its better to use "int items".
i would written "name[i]" instead of "*(name + i)".
and if you know the maximum size of strings you want to allow, if it's n, you can directly write :
for(int i=0; i<*items; i++)
{
cout << "Enter name #" << (i+1) << ": ";
name[i] = new char[n];
cin.getline( name[i] , n);
}

Related

Trying to read invalid data from array

#include<iostream>
#include<string>
#include<sstream>
#include <typeinfo>
using namespace std;
int main()
{
setlocale(LC_ALL, "");
string str = "5 7 3";
int length = str.length();
char* arr = new char[length];
cout << arr[2] << endl;
/*
int max = stoi(string(1, arr[0]));
for (int i = 0; i < length; i++) {
if(arr[i] != ' '){
if (stoi(string(1, arr[i])) > max) {
max = stoi(string(1, arr[i]));
}
}
}
cout << max << endl;
*/
delete[] arr;
}
I'm getting error C6385 " Reading invalid data" when I'm trying to cout arr[2]. When I'm trying to cout arr[0], for instance, I get char 'H' in console, I don't really understand why is there 'H' if I don't have H in my str
char* arr = new char[length];
cout << arr[2] << endl;
These are the only lines that matter for your question. The first one allocates a character array. The data stored in the array at this pointer is unknown. It could be zeroes, it could be complete garbage. In your case, there happens to sometimes be an 'H' in index 2. If you run it in a hour it could be different - likely the last thing stored at the memory address of that array element had an ascii value of H.
arr[] doesn't contain your str because you didn't do anything for that to happen. Also, to fit the string content , you would need new char[length + 1] to account for terminating zero.
After all, you don't need convert a string to an array in most cases, a string already contains i. There is std::stoi function that works with strings.
char* arr = new char[length];
that means, reseve memory and call it arr, it as memory as lenght char* size, this memory can conteins another runtime var or something unreadable for C++, so when u try:
cout << arr[2] << endl;
If u can read it, it will give you that value, as 'H', but if u cant it should get nothing or strange icon.
Just reboot PC and you arent going to get another 'H' on your arr[0]
Anyway as your code looks u need to change it:
char* arr = new char[length];
cout << arr[2] << endl;
for:
char* arr = new char[length + 1];

How I can handle with error about entered size of string exceeds the set size of char array?

I need some kind of error handler if I enter a string larger than the set size.
cout << "Enter long of the string" << endl;
cin >> N;
char* st = new char[N];
char* st1 = new char[N];
for (int i = 0; i < N; ++i) {
*(st1 + i) = ' ';
}
cout << "Enter string in the end put 0,without whitespace in the end." << endl;
cin.getline(st, N, '0');
First some comments.
Do not use C-Style arrays in C++ (like char data[N])
Always use std::string for strings
Never use char arrays for strings
Never ever use raw pointers for owned memory in C++
Neally never use new in C++
Avoid using pointer arithmetic with raw pointers pointing to owned memory
So, you should rethink your design. Start doing it correctly in the first place.
To answer you concrete question: If you read the documentation of the getline, then you can see that
count-1 characters have been extracted (in which case setstate(failbit) is executed).
So, the failbit will be set. You can check this with
if (std::cin.rdstate() == std::ios_base::failbit)
But as you can also read in the documentation
Extracts characters from stream until end of line or the specified delimiter delim.
So, it will not work, as you expect, It will try to read until 0 has been read. I think it will not work for you.
You also need to delete the newed memory. Otherwise, you are creating a memory hole. Look at you example again and try it:
#include <iostream>
int main() {
size_t N;
std::cout << "Enter maximum length of the string\n";
std::cin >> N;
char* st = new char[N];
char* st1 = new char[N];
for (size_t i = 0U; i < N; ++i) {
*(st1 + i) = ' ';
}
std::cout << "Enter string in the end put 0, without whitespace in the end.\n";
std::cin.getline(st, N, '0');
if (std::cin.rdstate() == std::ios_base::failbit) {
std::cin.clear();
std::cout << "\nError: Wrong string entered\n\n";
}
delete[] st;
delete[] st1;
return 0;
}
Solution for all your problems: Use std::string and std::getline

A simple vector, how can I reassign the address for a new array correctly

I am trying to create a simple version of a vector. It seems to be working if I look only at what I am storing, but there is one thing that concerns me. Here is my code:
#include <iostream>
using namespace std;
int main(){
char* arr = new char[1];
int size = 1; // current size of the array
int num_chars = 0; // how many characters are stored so far
char c;
while (true)
{
cout << ">";
cin >> c;
if (c == '!') break;
if (num_chars == size)
{
size *= 2;
char* new_arr = new char[size];
cout << "Old array address: " << &arr << endl;
cout << "New array address: " << &new_arr << endl;
for (int i = 0; i < size/2; i++) // copy arr to new_arr
new_arr[i] = arr[i];
delete[] arr;
arr = new_arr;
}
arr[num_chars++] = c;
for (int i = 0; i < num_chars; i++)
cout << arr[i];
cout << endl;
cout << &arr << endl;
}
delete[] arr;
return 0;
}
the program accepts characters one at a time, and they are stored in an array which grows dynamically, finishing when you enter an exclamation mark. I added some cout statements to check my input and where the arrays are being stored.
When I allocate new_arr it gets a new address, then I copy over the memebers of arr to the new arr, delete arr, and assign arr to point to new_arr. The part that concerns me is that when I check the memory locations of arr after it gets reassigned, it's the same as it was before, so it looks like I'm just writing past the end of the original array. How can I correctly reassign the pointer to the new array?
Here is some sample output:
>a
a
0x7fff5fbff760
>b
Old array address: 0x7fff5fbff760
New array address: 0x7fff5fbff748
ab
0x7fff5fbff760
>c
Old array address: 0x7fff5fbff760
New array address: 0x7fff5fbff748
abc
0x7fff5fbff760
You are printing out addresses of pointers themselves, not addresses of the arrays (i.e. the contents of the pointers).
The location in memory where you store the address of the array (i.e. the address of variable arr) stays the same. It's not supposed to change. Thus, &arr is always the same. But the value stored in that location does change (as it would be expected).
Change the code to
cout << "Old array address: " << static_cast<void*>(arr) << endl;
and see the difference.
(static_cast<void*>(arr) casts type of arr from char* to void*. The reason to do this is that cout treats char* as a pointer to null-terminated string, and prints the contents of the string instead of the pointer's value. However, if we change the type of the pointer to something that cout does not interpret (e.g. void*), then cout will just print the address.)

How to get the memory address of a pointer to a char[] in c++

Full disclosure: This is homework. I'm just really confused about one part.
I have this code in a c++ program:
char * charArray = new char[100];
//fill charArray
char c = '.';
for(int i=0; i<100; i++)
{
charArray[i] = c;
c = c + 1;
}
cout <<"Char Array: " << endl;
for(int i=0; i<100; i++)
{
cout << "Type: Char # " << &charArray[i] << " = " << charArray[i] <<endl;
}
At a different point in my program I have pretty much the exact same code but instead of a char array it is a float array. When I print out the float array I get Type: Float # whatAppearsToBeAProperMemoryAddress = correctFloat#.
However although the chars are correct the address don't appear to be. The address for the char array go like this:
./0123456789<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~??????????????????
/0123456789<=>?#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_abcdefghijklmnopqrstuvwxyz{|}~??????????????????
....
all the way to
??
?
So obviously instead of getting the address I am getting varying degrees of what should be the contents of the array. I am very confused and any pointers would be appreciated. This is my first crack at c++.
Because &charArray[i] is still a char* pointing to the ith character of the string. So it is used as a whole string. Try to cast as this:
(void*)&charArray[i]
that is the same as:
(void*)(charArray+i);

I am trying to return a Character Array but, I'm only getting the first letter returned

I'm working on a small little thing here for school. After hours of researching, and a ton of errors and logic reworking I've almost completed my little program here.
I'm trying to take user input, store it into the string, get a character array from the string ( dont ask why, I just have to put this into a character array ), then get the reversed order of the phrase that the user entered. Here is my code:
#include "stdafx.h"
#include <iostream>
#include <String>
#include <cstring>
using namespace std;
using namespace System;
#pragma hdrstop
char* getCharArray(string);
string reversePhrase( int, char* );
void main(void)
{
string sPhrase = "";
int sSize = 0;
string sReversed = "";
char* cPhrase = NULL;
cout << "Welcome to the You Type It & We'll Reverse it! [Version 1.0] " << endl;
cout << "This program will reverse your phrase, and count how many characters are in it!" << endl;
cout << "To begin just enter a phrase." << endl;
cout << "Enter a phrase: ";
getline( cin, sPhrase);
sSize = sPhrase.length();
cout << endl;
cPhrase = getCharArray(sPhrase);
sReversed = reversePhrase( sSize, cPhrase );
cout << sReversed;
system("pause");
}
string reversePhrase(int size , char* cPhrase)
{
string sReversed = "";
int place = size;
for ( int i = 0; i < size ; i ++ )
{
sReversed.append(1, cPhrase[place]);
cout << "Current string: " << sReversed << endl;
cout << "Current character: " << cPhrase[place] << endl;
place--;
}
return sReversed;
}
char* getCharArray(string sPhrase)
{
int size = 1;
size = sPhrase.length();
char* cArray = NULL;
cArray = new char[size];
for (int i = 0 ; i < size ; i++)
{
cArray[size] = sPhrase.at(i);
}
return cArray;
}
When I type in "ownage" into the program, this is what I get returned:
It is almost like my Character Array is getting garbage collected before it can use all of the characters. This is probably an easy fix but, I just don't see how I can get around this one.
Try rewriting getCharArray like this
char* getCharArray(string sPhrase)
{
int size = 1;
size = sPhrase.length();
char* cArray = NULL;
cArray = new char[size+1]; // NOTE
for (int i = 0 ; i < size ; i++)
{
cArray[i] = sPhrase.at(i); // NOTE
}
}
cArray[size]=0; // NOTE
return cArray;
}
Note that the assignment in the loop now uses the index variable. Also, you need to allocate one extra char in the array to set the null terminator for the string and then you need to set it at the end.
You'll also need to think about deallocating the array at some point
The bug is in this line:
cArray[size] = sPhrase.at(i);
That size should be your loop index.
You should probably look at using std::string more, and not poke around with character arrays when there's no need to.
Why use a char array at all? It's not only useless – it complicates the code substantially (the usage of your function is more difficult, and you've forgotten to free the memory allocated by new!). Why not just have the following function:
string reverse(string const& input);
(Passing the argument by const reference instead of by value saves you a copy!)
In fact, implementing the function only takes a single line using the features of the string class (one of its constructors takes two iterators):
string reverse(string const& input) {
return string(input.rbegin(), input.rend());
}
reversePhrase is also not correct. Try something like this:
string reversePhrase(int size , char* cPhrase)
{
string sReversed = "";
sReversed.resize(size);
int place = size - 1;
for ( int i = 0; i < size ; i ++ )
{
sReversed [i] = cPhrase[place];
cout << "Current string: " << sReversed << endl;
cout << "Current character: " << cPhrase[place] << endl;
place--;
}
return sReversed;
}
First, start the array with -1. After that, use a for loop with -1 and increment inside the loop. Then, you can get the first element of the array.