Entering data with pointers - c++

I am new to C++ but have many years of programming. All my learning has been very good until I reached pointers. I must admit am struggling to accomplish simple stuff. For example, after failing to store array data into pointers - and then list the pointers, I went basic with below to help me understand. In this, I am aiming to enter a list of names into array pointer (or something like that), then retrieve the list the values from the memory location.
a) I am not able to put this to allow request input and store to pointer
b) when I loop through a pointer, it only displays the first characters of the names. If someone can help me achieve the above, it will be my BIGGEST breakthrough in pointers.
please help;
CODE
#include "stdafx.h"
#include<iostream>
#include<cstring>
#include<cctype>
using namespace std;
int i=0;
int main(){
char* studentNames[6]={"John Xyy","Hellon Zzz","Wendy Mx","Beth Clerk", "Jane Johnson", "James Kik"};
int iloop = 0;
//loop through and list the Names
for(iloop=0;iloop<6;iloop++){
cout<<"Student :"<<studentNames[iloop]<<" Addr:"<<&studentNames[iloop]<<endl;
}
cout<<endl;
system("pause");
//Now try and list values stored at pointer memory location
int p=0;
for (p=0;p<6;p++){
cout<<*studentNames[p];
}
cout<<endl;
system("pause");
return(0);
}

a) I am not able to put this to allow request input and store to pointer
Use fgets() to read strings from stdin as follows. You have array of size 6 pointers to characters. Assuming the strings length to 100 characters each, for each string read from stdin allocate buffer memory and copy it to studentNames array of pointers everytime.
char *studentNames[6];
char input[100];
for (int str = 0; str < 6; str++) {
if (fgets(input, sizeof(input), stdin) != NULL) {
studentNames[str] = (char *)malloc(strlen(input));
strcpy(studentNames[str], input);
}
}
b) when I loop through a pointer, it only displays the first characters of the names.
//Now try and list values stored at pointer memory location
int p = 0;
for (p = 0; p < 6; p++){
cout<<*studentNames[p];
}
In the above string printing, *studentNames[p] dereferences pth array of pointer each time in loop which prints first character only. Replace it with studentNames[p] which prints string literals.

Related

Not able to input strings using getline() .It is reading only one string

char* name[4];
int j=0;
while(cin.getline(name[j],80))//input given:you(ent)me(ent)he(ent)she
cout<<name[j++];
this code is reading only one string upto one newline.should'nt it read all 4 strings and print them ?and is this a good way to input string using getline?
Problem: You are not allocating the memory properly. You are declaring an array of pointers not an array of c style strings.
Possible Solutions: You need to read about pointers and memory allocation first. You can either allocate memory first to each of the four pointers that you declared name[0], name[1], name[2], and name[3] using the following code:
char* name[4];
for (int i = 0; i < 4; i++)
{
name[i] = new char[80];
}
OR you can use a 2D array for which the code is posted below:
char name[4][80];
int j=0;
while(j<4 && cin.getline(name[j],80))
{
cout<<name[j++];
}
I made a bit of correction. And it works on my computer.
char* name[4];
for (int i = 0; i < 4; i++)
name[i] = new char[80];
int j = 0;
while (j < 4)
{
cin.getline(name[j], 80); //input given:you(ent)me(ent)he(ent)she
cout << name[j++] << endl;
}
You need to read some more about pointers, arrays and memory management in C++ i guess. You try to operate on C array of strings, but you didn't initialize it properly. You need to allocate memory before you use such pointers. Currently your program results in UB so you are actually really lucky that it did anything same at all.
Another issue is that, when you reach the end of your input, when j=4, you will still attempt to perform cin(getline(name[j], 80) but you are passing the name[4] as a parameter, which may be a cause of another UB, even if you allocate the memory correctly beforehand.
Other then that you are writing in C++, so use C++ string and vector instead of C arrays.
This is easily done with strings and std::getline:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<string> names;
string name;
while(getline(cin, name)){
names.push_back(name);
cout<<name<<endl;
}
return 0;
}

Pointer to an array of cstrings declared dynamically

char ** ptr = new char *[3];
ptr[0] = new char [5];
ptr[1] = new char [6];
ptr[2] = new char [7];
cout<<"Enter first array: ";
cin.getline(ptr[0], 5);
cin.getline(ptr[1], 6);
cin.getline(ptr[2], 7);
for (int i=0; i<3; i++){
cout<<ptr+i<<endl;
}
for (int i=0; i<3; i++){
delete[] ptr[i];
}
When I run this code, it gives the following output:
Enter first array: name
0xf99c20
0xf99c28
0xf99c30
I actually wanted the user input printed out.
Could someone please tell me how to do this?
The type of ptr+i is char**, not char*, so is just being printed as a pointer. To have it print as a string, use ptr[i], which is a char*.
That said, use a std::vector<std::string>. Then you can use the string version of std::getline. Then you avoid many possible problems with matching up new and delete, leaks, dealing with longer user input, dealing with a different number of lines of user input, etc.
Also, please reconsider your use of what are often considered bad practices: using namespace std; and endl (those are links to explanations).
you have logic misunderstanding of pointer concept when you print ptr+i it will give you the actual address locations of your inputs in the memory
to print the value of pointer you can use:
*(ptr+i)
or :
ptr[i]
also getline (char* s, streamsize n ); max stream size of your inputs should be bigger because there is a null character '\0' at the end of each character sequences and newline character '\n' when you enter another input:
cin.getline(ptr[0], 10);
cin.getline(ptr[1], 10);
cin.getline(ptr[2], 10);
link to the solution:
https://ideone.com/maSOSs

dynamic memory allocation of strings in cpp

so here's the thing I've been working on a code for 5 hours now and logic looks good the program seems to do it's job, the only thing that keeps bugging me is dynamic memory allocation of strings. The question does not specify the initial number of strings user has to enter. Here's what I've been trying to do to dynamically take the strings :
int t;
cin>>t //number of strings user wishes enter
char *s1[1000009]; //1000009 is the maximum number of digits each string can have
for(i=0;i<t;i++)
{
s1[i]=(char *)malloc(1000009)
cin>>s1[i];
}
not sure if it is the right way or not. A way through which i could store a 2D character array would also do if not dynamic strings.
Thanking you,
gaurav
Use a vector of strings instead of using malloc/new.
int t;
std::cin >> t;
std::vector<std::string> strings(t); //Create t strings
for(int i = 0; i < t; i++)
std::cin >> strings[i]; //Read into each string
Since you tagged this question as C++ I would do it like this:
std::vector<std::string> s1(1000009);
That's all - no need to use malloc, no need to take care about destruction.
If you are using C++ use the Tools you have available.
i would do it like this :
int i = 0;
char **s1;
s1 = (char **)malloc(t * sizeof(char *));
while (i < t)
{
s1[i] = (char *)malloc(1000009 * sizeof(char));
i++;
}
the first malloc create you t line.
The second one fill alloc 100000009charactere for each lines

why char array's size is same using sizeof()

I meet a problem with the char array size. I pass an char array into the function and after run the function, I still want to use sizeof to check the size of the array, it won't give me the new size of the array, but the old size? I would like to know why? Thank you very much!
#include<iostream>
using namespace std;
void replacement(char* arr, int len){
int count=0;
for(int i=0; i<len; i++){
if(arr[i]==' '){
count++;
}
}
int newlen=count*2+len;
//arr[newlen]='\0';
int k=newlen-1;
for(int i=len-1; i>=0; i--){
if(arr[i]!=' '){
arr[k--]=arr[i];
}
else{
arr[k--]='0';
arr[k--]='2';
arr[k--]='%';
}
}
}
int main(){
char arr[]="ab c d e g ";
cout<<sizeof(arr)<<endl;
replacement(arr, sizeof(arr));
int i=0;
while(arr[i]!=NULL) cout<<arr[i];
}
You can't change an array's size. If you want to know the length of the string in the array, use strlen() -- this counts the number of characters before the null terminator.
Even better would be to use C++ std::string class.
Right, so you are trying to replace spaces with "%20", right?
Since C++ (or C) doesn't allow an existing array to be resized, you will either need to have enough space in the first place, or use an array allocated on the heap. Then allocate a new "replacement" string in the replacement function and return that.
The proper C++ method of doing this is of course to use std::string, in which case you could just pass it in as a reference, and do the replacement in the existing variable:
void replacement(std::string* str, int len){
std::string perc20 = "%20";
std::string space = " ";
while((pos = str.find(space, pos)) != std::string::npos)
{
str.replace(pos, space.length(), perc20);
pos += perc20.length();
}
}
Much easier...
You can use sizeof() to find the size of only static arrays when the size is known at compile time. Hence it will always return the size of the array as determined at compile time.
Your program technically has Undefined Behavior because your use of sizeof returns the size in bytes of your char array. But a char implicitly contains a null byte \0. That means the for loop is iterating 1 past the length of the array.
It's recommended that you use std::string along with its size member function instead.

pushback data from vector to vector of map

i have created a map called select_p and vector of this map is called pts. i have stored data in a array and i want to pushbcak these data into my vector of map. i tried this by inserting value of array into new vector and then pushback into my map.but it is not working please help me to correct these codes? thanks
#include<iostream>
#include<cstdlib>
#include <map>
#include <vector>
using namespace std;
int main()
{
int M=7;
int N=6;
int i=0;
int * temp;
map<int,vector<int> > select_p;
vector<int>pts;
for (int m=0; m<M; m++)
{
for (int n=0; n<N; n++)
{
vector<int>id;
if (n==0 && m==5)
{
temp = new int[3,i+N,i+N+1,i+1];
unsigned ArraySize = sizeof(temp) / sizeof(int);
id.insert(id.begin(),temp[0], temp[ArraySize]);
select_p[i].push_back(id);
}
i++;
}
}
delete[] temp;
system("PAUSE");
return 0;
}
for (int m=0; m<M; m++) {
for (int n=0; n<N; n++) {
if (n==0 && m==5) {
Why are you looping when you only actually do anything for a single pair of values of m and n? The loops are completely useless here; you would get the same effect by just setting n = 0 and m = 5.
temp = new int[3,i+N,i+N+1,i+1];
Whatever you think this does, that's not what it does. This is equivalent to temp = new int[i+1];. The rest of the expression inside of the [] has no effect.
That said, you should not use new to create arrays in your program. Use std::vector; it is far easier to use correctly.
unsigned ArraySize = sizeof(temp) / sizeof(int);
This does not work. When you dynamically allocate an array, you are responsible for keeping track of how many elements are in it. Given a pointer to a dynamically allocated array (like temp here) there is no way to determine the number of elements in the array.
What you have is equivalent to sizeof(int*) / sizeof(int), which is not going to do what you expect.
id.insert(id.begin(),temp[0], temp[ArraySize]);
std::vector::insert takes a range of iterators: you have provided it with two values. Presumably you want to use temp, which points to the initial element of the dynamically allocated array, and temp + i + 1, which points one past the end of the array. That said, since you haven't set the values of the elements in the array, you are copying uninitialized memory, which probably isn't what you mean to do.
select_p[i].push_back(id);
select_p[i] is a std::vector<int>. std::vector<int>::push_back() takes a single int that is appended to the sequence. Presumably you just mean to use assignment to assign id to select_p[i].
You should get a good introductory C++ book if you want to learn to program in C++. I am sorry to say that your program is nonsensical.