can someone help me here. I am experimenting on copying an array of characters using char array (in the first case) and using a pointer(in the second case) I understand why I need a temp[i]='\0' immediately after the while loop in the first case but I dont understand why I dont need it after the while loop in second case.
1st case:
char source[50] = "Hello World";
char temp[50];
int i = 0;
while (source[i] != '\0')
{
temp[i] = source[i];
i++;
}
temp[i]='\0';
cout << temp;
2nd Case:
char source[50] = "Hello World";
char *temp=source;
int i = 0;
while (source[i] != '\0')
{
temp[i] = source[i];
i++;
}
cout << temp;
I understand why I need a temp[i]='\0' immediately after the while loop in the first case
Right, because you stopped the loop just before copying the '\0', so you have to do so artificially at the end.
I dont understand why I dont need it after the while loop in second case.
Because temp is not a new array — it's just a pointer to the elements of the old one. Every single assignment in that loop is like x = x: you're just overwriting an array with itself.
You don't need to add a '\0' because the source array is the destination array, so it's already there.
In logical terms, the code in the second case achieves nothing.
Related
I need help removing spaces and special characters from an char array.The problem I keep running into is that the erase function only works on string datatypes, if I'm not mistaken. The assignment calls for a char array not a string so I cant just convert it or have a string variable. I've tried looking it up but everything kind of just suggests to convert it to a string or start off as a string, which I can't do. I'm new to programming and pointers are a little weird to me so if the answer is obvious I am sorry.
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <ctype.h>
using namespace std;
int main()
{
const int SIZE = 80;
char str[SIZE];
char* strPtr;
int strlength;
int j = 0;
int front = 0, back; int flag = 1;
strPtr = str;
cout << "This program checks for palidromes." << endl;
cout << "Please enter a phrase." << endl;
cout << endl;
cin.getline(str, SIZE);
//Get the length of string str
strlength = strlen(str);
//Convert all the characters in the string str to uppercase
for (int i = 0; i < strlength; i++)
{
if (!isupper(str[i]))
str[i] = toupper(str[i]);
}
//Remove all the special characters except letters a - z
for (int i = 0; i < strlength; i++)
if (!isalpha(str[i])||(!isalnum(str[i])))
{
str.erase(str[i]); // need help here. Not sure how to go about it.
}
//str[j] = '\0';
return 0;
}
char* tail = std::remove_if(str, str + strlength,
[](char c){ return !isalpha(c)||(!isalnum(c)); });
strlength = tail - str;
*tail = 0;
The other answer correctly points you to std::remove_if, but I suspect that you really want to understand how to implement the removal yourself, instead of dumping the problem on the C++ library. Also your own attempt at this converts all remaining characters to uppercase, which the other answer does not do.
This is actually simpler than you might think. The relevant bits are as follows:
char *p=str, *q=str;
while (*p)
{
if (isalpha(*p))
*q++=toupper(*p);
++p;
}
*q='\0';
For starters, there's no need to compute strlen() of this string. Simply iterating a pointer from the beginning of the string to the end, until it's pointing at the terminating '\0' is sufficient.
That would be the p pointer. p starts at the beginning of the string, and each iteration of the while loop increments it, with the while loop stopping at the \0.
Then, if p's character is alphabetic, it gets copied to the q pointer, converting it to uppercase, and advancing the q pointer too.
As such, only alphabetic characters get copied to q, everything else gets skipped.
q starts off pointing to the same buffer as p, the buffer with the string. If the string begins with alphabetic characters, the only thing that will happen is that each character gets copied on top of itself, with both p and q advancing together. As soon as p sees a non-alphabetic character, it continues to advance, but q is "left behind", and will continue to accumulate only any remaining alphabetic characters. And when everything is done, the '\0' gets written to q, terminating the new uppercase-only string.
The only real difficult part of this is understanding why everything must occur exactly in the sequence; i.e. the alphabetic character must be copied before p gets incremented, etc... Talk to your rubber duck, if you do not understand why, your rubber duck will explain it to you.
I need reverse my char string only with pointers. How can I do this? My code:
// this cannot be modified !!!
char s[10] = "abcde";
char *pS;
// my code
pS = new char;
int count = 5;
for (int i = 0; i < 10; i++)
{
if (s[i] != '\0') // not null
{
pS[count - 1] = s[i];
count--;
}
}
cout << "Reversed = " << pS;
Sometimes if works fine, I see only 5 chars, they are reversed. But sometimes I see some extra chars (looks like temp symbols). Where I miss something? Thank you!
your char array "s" contains 10 chars, but you only initialize the first 6 chars of that array with "abcde" and the \0 terminator.
When you loop over the complete array, you access not initialized chars.
I also see, that you try to write to memory, which you didn't allocate.
You only allocate memory for 1 char for you "pS" pointer, but you try to access it's memory like it is an array of chars in your for-loop.
Instead of using hardcoded:
int count = 5;
you also could use the string function strlen() to determine the length of the c-string.
Edited (untested code):
char s[10] = "abcde";
char pS[10];
for (int i = 0; i < strlen(s); i++)
{
if (s[i] == '\0') // not null
{
// stop loop, as soon as you reach the end of the original string
break;
}
pS[strlen(s) - 1 - i];
}
// now add the termination char \0 to your pS array
pS[strlen(s)] = '\0';
cout << "Reversed = " << pS;
Just giving you the hint how to reverse the string using pointers:
Take two pointers front and rear where front is pointing to first char of string and rear is pointing to last char of string.
Check if front is less than rear
If yes, swap the value of first and last character. If no , just print the string.
Increment front pointer and decrement rear pointer
Repeat from step 2.
After reading another book I fully understand pointers and how to correctly allocate memory. Here is my final code which correctly reverse array of char string (I don't need universal code, just working example + without std methods for reversing):
// not edited part - based on exercise (I mean I cannot change pS to char[5] etc.
char s[10] = "abcde";
char *pS;
pS = new char[strlen(s) + 1]; // allocate correct memory size based on string size
cout << "Size is " << sizeof(pS) << endl; // just for testing
int count = strlen(s); // for iteration
pS[count] = '\0'; // last symbol must be '\o' (thanks to Mr.Yellow)
for (int i = 0; i < 10; i++) // 10 because array of char still has 10 elements
{
if (s[i] != '\0') // looks like "not garbage memory"
{
count--;
pS[count] = s[i]; // set correct value
}
}
cout << "Reversed = " << pS << endl;
Thank you to all who helps me!
I am writing a C++ function that is supposed to duplicate an array of chars by copying each element character-by-character into a new array. Ideally, if I make the statements
char* a = "test";
char* b = copyString(a);
then both a and b should contain the string "test." However, when I print the copied array b, I get "test" plus a series of nonsense characters that seem to be the pointer. I don't want those, but I can't figure out where I'm going wrong.
My current function is as follows:
char* copyString(char* s)
{
//Find the length of the array.
int n = stringLength(s);
//The stringLength function simply calculates the length of
//the char* array parameter.
//For each character that is not '\0', copy it into a new array.
char* duplicate = new char[n];
for (int j = 0; j < n; j++)
{
duplicate[j] = s[j];
//Optional print statement for debugging.
cout << duplicate[j] << endl;
}
//Return the new array.
return duplicate;
}
For the purposes of understanding certain aspects of C++, I cannot use string libraries, which is where other answers I have found have fallen short in this case. Any help with this problem is greatly appreciated.
EDIT: I though my stringLength function was fine - perhaps I was wrong.
int stringLength(char* s)
{
int n;
//Loop through each character in the array until the '\0' symbol is found. Calculate the length of the array.
for (int i = 0; s[i] != '\0'; i++)
{
n = i + 1;
}
//Optional print statement for debugging.
// cout << "The length of string " << s << " is " << n << " characters." << endl;
return n;
}
You need to copy the 0 too. That's what a C-style string is, a null-terminated character array.
Really, all you need to do is add one to the length:
int n = stringLength(s) + 1; // include the '\0'
And then everything else will account for itself - you'll allocate an array of sufficient size, and copy the '\0' in your loop too.
I'm learning to use pointer to copy char array.
I have the following code in C++. What I'm trying to do is to transfer and array (set1) using pointer to another pointer array (temp).
But when I try to print out (temp), it is not the same as (set1).
Transfer an array via pointer to another temp array pointer.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
char set1[] = "ABC";
char* p = &set1[0];
int tempSize = 0;
char* temp = new char[256];
for (int i = 0; i < 3; i++)
{
*temp = *p;
cout << *temp; // ABC
++temp;
++tempSize;
++p;
}
cout << "\n";
for (int i = 0; i < tempSize; i++)
{
cout << temp[i]; // Why ABC is not printed?
}
delete [] temp;
return 0;
}
// Why ABC is not printed?
Because your pointer is travelling in undefined behavior region:
char* temp = new char[256];
...
++temp; // gone !!
On top of that,
you are not terminating the string with \0 in the end (may not be needed in your code)
delete[]ing this corrupt pointer in the end.
Since you are writing for learning purpose, I would suggest simple fix to your code:
char* const temp = new char[256];
^^^^^ ensures `temp` is not modifiable
Now use temp[i] for traversing purpose.
It's because in the loop copying the array, you change temp. After the loop, it points to one beyond the copied data.
Also, you forget to terminate the new allocated array. You should add the character '\0' at the end.
The problem is this line:
++temp;
You are incrementing the pointer and then write to it. In the end temp[i]; does not point to the beginning of your string, but to the end.
The easiest way to do this is to remove the first for loop with:
for (int i = 0; i < 3; i++)
{
temp[i] = set1[i];
}
temp[4] = '\0'; // don't forget to close the string
C-style strings have a null terminator - "ABC" contains four characters. Also, I'm not at all sure that the delete call on temp is valid - you have been incrementing it since it was 'newed'.
I'm a beginner and i need to ask a question..
I wrote this small code that accepts a string from the user and prints it..very simple.
#include <iostream>
using namespace std;
int main()
{
int i;
char *p = new char[1];
for(i = 0 ; *(p+i) ; i++)
*(p+i) = getchar();
*(p+i) = 0;
for(i = 0 ; *(p+i) ; i++)
putchar(*(p+i));
return 0;
}
when i enter any string..like "stack overflow" for example..it will print "sta" and drop the rest of the string. I know it's an easy one to solve but since I've just started i can't understand what's wrong here . Thanks in advance .
There are several problems with this code. First, you have a buffer overflow, because char *p = new char[1] allocates only one character for storage. This is exceeded when i > 0. Next, your first loop will keep going until it reaches a point in unallocated memory (undefined behavior) that has a value of zero. This just happens to be after the third value in your case. You probably wanted something more like *(p+i-1) == 0 to give "the last character read meets some condition." Finally, you're allocating memory with new[] and not properly deallocating it with a matching delete[].
Consider using std::cin and std::string for much safer and correct code:
#include <iostream>
#include <string>
int main(int, char**) {
std::string s;
std::cout << "Enter a string: ";
std::cin >> s;
std::cout << s << std::endl;
}
Here is some code along your lines that seems to work. I'm sure there are better (and more C++-ish) ways to do this...
#include <iostream>
using namespace std;
#define MAXLEN 80
int main()
{
int i=0;
char c;
char *p = new char[MAXLEN + 1]; // 1 char will not be sufficient
do // Doing this with a for loop would be unreadable
{
c = getchar();
*(p+i) = c;
i++;
} while( c != '\n' && i < MAXLEN ); // Check for a newline. How do you enter the zero with a keyboard?
*(p+i) = 0; // Ensure that the last character is zero
for(i = 0 ; *(p+i) ; i++) putchar(*(p+i)); // This is OK but difficult to read
delete [] p; // Don't forget this
return 0;
}
The fact that your program does anything is just luck; what stops *(p+i) from being \0 to begin with? It's weird that you're using getchar() and putchar() in a C++ program, too. What's the story behind this program?
If you read into memory, be sure that you allocate enough. new char[1] creates an array of only one char, but you are reading more then that. A simple temporary fix would be to simply allocate more, say new char[255].
Other notes:
you never delete the memory you allocated: delete[] p;
you should check wether you read as much characters as your buffer can hold: for(..;.. && i<bufferSize;..)
the condition in the first loop always checks the next character, not what you just read
*(p+i) is equivalent to p[i], which is more readable
why read and write only one character at a time?
why not use iostreams (std::in, std::out) and std::string as you are using C++?
you only allocate space for one character but you try to put many chars in it.
Is this homework? if so please tag it as such. Are you allowed to use STL?
If so then use std::vector instead on new char[1];
EDIT:to do it without any fiddly bits or STL
const int MAX = 100;
char *p=new char[MAX];
for(i = 0 ; *(p+i) && i < MAX ; i++)
*(p+i) = getchar();
probably some out by ones - left as exercise