Use Strcpy_s to Copy Dynamically Allocated Char Array - c++

I'm simply trying to copy what is in 'temp' into 'p' but the program crashes on the strcopy_s line. Am I missing some important rule?
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main() {
char temp[100] = "Coolbeans";
int len = strlen(temp);
char* p = new char[len+1];
strcpy_s(p, len, temp);
for (int i = 0; i < len; i++)
cout << p[i] << endl;
for (int i = 0; i < len; i++)
cout << temp[i] << endl;
}

Praetorian hit it on the head. "The important rule you're missing is use std::string". Old C functions like strcpy_s are notoriously incredibly unreliable and that's the whole point of not doing it anymore. So don't do it. Use std::string.

The above code snippet result in "Debug Assertion failed" run time error.
strcpy_s(p, len, temp); //Expression:(L"Buffer is too small" &&0)
So the answer is strcpy_s(p, len+1, temp); will work fine in your case.

Related

Reversing characters from input

I am trying to reverse a char which has been provided in input from an user. I am having issues with the reverse function, particularly the loop. I can't get it to work- can I get advice?
#include <iostream>
using namespace std;
#include <cstring>
char* reverse(char* input) {
int len = strlen(input);
char temp[len];
for(int i=len; i>len; --i) {
temp[i]+=input[i];
}
return temp;
}
int main()
{
char input[100];
while(cin>>input) {
cout << reverse(input);
}
return 0;
}
Your Program has few issues
You're trying to return local variable address i.e. temp array address. The Function will return the address to main function. Since memory might get cleaned so it will print garbage value present at the address.
As Rohan Bari mentioned variable length array might cause undefined behavior. There for you can create a constant length array i.e.
char temp[100];
or you can dynamically allocate array on heap. Memory allocated on heap do not get cleared after termination of block but we have to manually delete it.
char* temp = new char[len];
As array start from 0 it goes till len-1 so loop condition should start from len-1 and has to go till 0 to reverse.
+ operator do not work's with array or char even if you are trying to add just char it preforms normal integer addition of their ASCII value.
Here is improved version of your code
#include<iostream>
using namespace std;
#include <cstring>
char* reverse(char* input) {
int len = strlen(input);
char* temp = new char [len]; // or you can use char temp[100];
int j = 0; //temp variable to enter values from 0th index if we use same as loop it just enter in the same order as original char array.
for(int i=len-1; i>=0; --i) {
temp[j++] = input[i];
}
temp[j] = '\0';
return temp;
}
You have got several errors in the program.
The variable-length arrays are used here:
char temp[len];
This should not be applied in C++ since this invokes undefined-behavior. Note that this is a valid statement in the C99 standard.
There is a better alternative to this. That is to take the std::string built-in type in use.
In the following line:
temp[i] += input[i];
You are not sequentially adding one character after another, but the values of them in a single integer. This could be not a problem if temp was of the type std::string.
The reverse function should look like this:
const char *reverse(char *input) {
int len = strlen(input);
std::string temp;
while (len--)
temp += input[len];
return temp.c_str();
}
len should actually be (len-1) and i should be >= 0 not len, so from (len-1) to 0 your loop should run.
for(int i = len-1; i >= 0; i--){}
You have to allocate the new array with the new keyword if you don't want to use a string. The following code does what you need:
char* reverse(char* input)
{
int len = strlen(input);
char* temp = new char[len + 1];
for (int i = len; i >= 0; --i)
{
temp[len-i-1] = input[i];
}
temp[len] = '\0';
return temp;
}
You could use a std::stack to reverse your input:
std::stack<char> s;
char c;
while (std::cin >> c)
{
s.push(c);
}
while (!s.empty())
{
std::cout << s.top();
s.pop();
}
It's 2021. Use the STL. If your instructor isn't aware of it or doesn't allow you to use it, your instructor is not keeping up-to-date and you should fire your instructor.
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string input{};
while(std::getline(std::cin, input)) {
std::reverse(std::begin(input), std::end(input));
std::cout << input << '\n';
}
return 0;
}
There's quite many things wrong with the code as many people have already mentioned! Since you want to implement this without using STL it can be done this way,
#include <iostream>
using namespace std;
#include <cstring>
void reverse(char* input,int len) { //added len as argument
char temp[len];
for(int i=len-1; i>=0; --i) {
temp[len-i-1]=input[i];
cout<<temp[len-i-1]; //printing while reversing
}
cout<<endl;
}
int main()
{
char input[100];
int len=0;
//using do while since it has to run atleast once
do{
cin.getline(input,100);
len=strlen(input);
input[len]='\0';
if(len!=0)
reverse(input,len);
}while(len!=0) ;
return 0;
}

Why do I get different results for this cout of pointer of char?

I get two different results for writing the same thing, but in different functions.
I'm trying to create an array of char, letter by letter, and then I put it in a char **v. As you can see, I have cout v[i] inside create_vect(), as well as in main() function, and if I run the code, I get different results each time. I'm confused. Why is that and what could I do to troubleshoot it so that I also get '000' as result the second time as well, as I'm aiming for?
#include <string.h>
#include <math.h>
using namespace std;
void create_vect( char **&v){
v=new char*[3];
for (int i=0;i<3;i++){
char wordd[4];
wordd[0]='0';
wordd[1]='0';
wordd[2]='0';
wordd[3]='\0';
v[i]=wordd;
cout<<endl<<v[i]; //here I get the right thing
}
}
int main(){
char **v;
create_vect(v);
for (int i=0;i<3;i++){
cout<<endl<<v[i]; //here i get something weird ascii sign
}
}
edit:My bad, I just wanted to translate it into English, so that it would be easier to see what I'm aiming for with my code and I missed a word. I'd really appreciate your help as in what changes I need to make for it to work. I'm a bit lost. Thank you and sorry again for my careless mistake.
When you call create_vect and enter the for loop you create a variable wordd of type char[4] on the stack. But it's lifetime is only the one iteration of the for loop. With v[i]=wordd; you assign the address of the first element of wordd to v[i]. An array decays to a pointer to the first element. As long as the variable wordd exists, you can print it. But when you try to access the memory after the lifetime ends, you get undefined behavior. Sometimes your program could work as expected and sometimes it will print garbage.
To fix your problem you can either use dynamic memory allocation on the heap or you can use a stl container like std::vector<std::string> (which probably uses dynamic memory allocation and is copied by value). Remember to clean up dynamically allocated memory.
Also you shouldn't use c headers (math.h, string.h) in c++ code. Use cmath, cstring. Don't use using namespace std;. Use std::cout, std::endl, ...
#include <cstring>
#include <cmath>
#include <iostream>
void create_vect(char **&v) {
v=new char*[3];
for (int i = 0; i < 3; ++i) {
v[i] = new char[4];
v[i][0]='0';
v[i][1]='0';
v[i][2]='0';
v[i][3]='\0';
std::cout << std::endl << v[i]; //here I get the right thing
}
}
int main(){
char **v;
create_vect(v);
for (int i = 0; i < 3; ++i) {
std::cout << std::endl << v[i]; //here i get something weird ascii sign
}
// Clean-up
for (int i = 0; i < 3; ++i) {
delete[] v[i];
}
delete[] v;
return 0;
}
I am not so sure what you were trying to achieve but maybe it was this:
#include <string.h>
#include <math.h>
#include <iostream>
void create_vect(char *&v){
char wordd[] = {'0', '0', '0'};
v = new char[3];
for (int i=0; i<3; ++i){
v[i] = wordd[i];
std::cout << v[i] << std::endl;
}
}
int main(){
char *v;
std::cout << "inside the function" << std::endl;
create_vect(v);
std::cout << "outside the function" << std::endl;
for (int i=0;i<3;++i){
std::cout << v[i] << std::endl;
}
delete[] v;
return 0;
}
Or what #ThomasSablik suggested, In which Please note:
When a function is returned (function is called and ended) all of the local objects inside the function are destructed and the memory which they were occupying is released.
As a result it is wrong to create an object (char* in this case) inside a function and assigning it address to a non local pointer (char** in this case) in the hope of using the pointer afterwards!

strlen to int c++ - Why can't I do this?

Where is this code wrong?
It won't let me cast strlen(s) into an int that I can iterate it until i is equal to the length of the string.
#include <iostream>
#include <string.h>
#include <string>
using namespace std;
int main()
{
string s;
cin >> s;
for (int i = 0; int n = (int)strlen(s); i < n, i++)
{
cout << s[i] << endl;
}
}
The problem is not that the result of strlen can't be cast to an int, but that strlen can't be used with std::string.
strlen is for "C strings", zero-terminated arrays of characters.
std::string has a size member function:
int main()
{
string s;
cin >> s;
for (int i = 0; i < s.size(); i++)
{
cout << s[i] << endl;
}
}
There is nothing inside the C header <string.h> that applies to std::string.
A reference can be useful.
strlen is for char arrays.
std::string has a member function called size and length.
If you still want to use strlen, you can call c_str and pass the returned string to strlen.
std::size_t length = s.size();
for (int i = 0; i < length; ++i)
You can also iterate over the elements of the std::string:
for (std::string::iterator itr = s.begin(); itr != s.end(); ++itr)
{
std::cout << *itr << std::endl;
}
Because strlen expects to get a char const* as it's argument. You should probably use s.size() instead as s is a std::string.
In addition you should probably not compute strlen inside a loop like that due to performance issues (s.size on the other hand should be able to complete in O(1) time so it would be OK).
Then there's a few other problems with your program, already at line one. You can't include a file by using #include //iostream, you should use #include <iostream> instead.
Second you cannot declare a variable in the condition of a for loop as you try to do, and you probably shouldn't assign instead of comparing (one equal sign is not the same as two). You should have written for( int i = 0; i != s.size(); i++ )
Third you shouldn't do the check in the update expression in the for construct. What goes there will only be evaluate to update the loop variables and such and the truth value will be disregarded.
Overall I think you should pick up an introduction to C++ book or find a good tutorial online. Your code simply has to much problems to conclude that you have learnt even the most basic C++.

Reversing the sequence of a string [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
A fairly simple program, trying to reverse the characters in a null terminated string in C++, but something seems to be going wrong.
#include <iostream>
using namespace std;
void reverse(char*);
int main(){
char *str;
cout<< "Please enter a string, no spaces please..";
cin >> str;
//reverse(str);
}
void reverse(char *str){
char temp;
size_t len = strlen(str);
for (size_t i = 0; i < len/2; i--)
{
temp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = temp;
}
}
Getting the following error
Bus error: 10
Any help appreciated.
Allocate memory for str before use char *str = new char[25];
In reverse function for for loop increment i for (size_t i = 0; i < len/2; i++ )
Deallocate memory after use delete [] str ;
You are decrementing iterator i insted of incrementing it. A little bit compact version of yours:
#include <algorithm>
#include <cstring>
void reverse(char* const str)
{
unsigned long const len = strlen(str);
for(unsigned long i = 0; i < len >> 1; i++)
std::swap(str[len - i - 1], str[i]);
}
#include <algorithm>
#include <string>
#include <iostream>
#include <cstring>
int main() {
// You can't read something to nowhere.
// String will be holded in static array.
char str[1024];
// To keep it as null terminated string after
// writing of inputed string: `std::cin` don't
// write null character after writing of data.
memset(str, 0, 1024);
std::cin >> str;
// If you do reversing of strings in C++,
// you shouldn't use hand written loops:
std::reverse(str, str + strlen(str));
std::cout << str << std::endl;
}
Try this modified version of your code:
#include <iostream>
#include <cstring>
using namespace std;
void reverse(char*);
int main(){
char str[1024]; // buffer of 1024 chars
cout<< "Please enter a string, no spaces please..";
cin >> str;
reverse(str);
cout << "\nReversed: " << str;
}
void reverse(char *str){
char temp;
size_t len = strlen(str);
for (size_t i = 0; i < len/2; i++) // loop until half of the user input
{
temp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = temp;
}
}
I simply added the array of char char str[1024]; to store the user input.. and changed the loop to: for (size_t i = 0; i < len/2; i++)
However, you must be very careful with the above code.. it works properly if the size of the input is less than the array fixed size.

Unable to store value in array in c++

What i'm willing to do is i wanna convert all the values of the array to their respective ASCII values and then store them in another array. My code is able to convert the character values into ASCII but it fails in storing them in another array. Please help me out.
#include <iostream>
#include <string>
using namespace std;
int main(){
char ass[10];
char name[]= "Chaitanya";
int size=sizeof(name);
for(int i=0; i<size; i++){
int p=name[i];
cout<<p<<"\n";
for(int j=0; j<size; j++){
ass[j]=p;
}
}
return 0;
}
When I try to run this program I get the following error message:
warning: variable ‘ass’ set but not used [-Wunused-but-set-variable]
Thank You!
I got the previous one. But what if i wanna print all those elements stored in ass once again. I'm using the following code and it does nothing. I'm not getting any error.
#include <iostream>
#include <string>
using namespace std;
int main(){
char ass[10];
char name[]= "Chaitanya";
int size=sizeof(name);
for(int i=0; i<size; i++){
int p=name[i];
cout<<p<<"\n";
for(int j=0; j<size; j++){
ass[j]=p;
}
}
for(int q=0; q<size; q++){
cout<<ass[q];
}
return 0;
}
Your warning is not a failure. It's just pointing out that once you store it, you never use it!
Your warning is just telling you that you aren't using the variable ass. It's not an error, but you do have a problem in your code:
int size = sizeof(name);
for (int i = 0; i < size; i++)
{
int p = name[i];
for (int j = 0; j < size; j++)
{
ass[j] = p;
}
}
The second for loop will simply overwrite each character in ass with the single character p. A nested for loop isn't needed, just assign the character from the main loop:
for (int i = 0; i < size; i++)
{
int p = name[i];
ass[i] = p;
}
Moreover, this can be facilitated through the Standard Library functions. For example:
#include <iostream>
#include <string>
int main()
{
std::string ass;
std::string name = "Chaitanya";
for (auto a : name)
{
std::cout << static_cast<int>(a);
}
ass = name;
std::cout << ass; // "Chaitanya"
warning: variable ‘ass’ set but not used [-Wunused-but-set-variable]
This warning just say that you have set the variable ass but you never use it. It is not an error at all.
As an example, try to output a value for this array and the warning will disappear:
std::cout << ass[0] << std::endl;
There is a little part on this warning here: http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html.
The warning is correct, you only set the values of ass you do not use the values set afterwards. If you added let's say a cout after the loop the warning would go away:
std::cout << ass[0] << std::endl ;
I also, don't think you need the second inner loop, if you want to print out each element of ass you could add it that after you set it. So the fix and additions print out could look like this:
for(int i=0; i<size; i++)
{
int p=name[i];
cout<<p<<"\n";
ass[i]=p;
std::cout << ass[i] << std::endl ;
}