I'm using C++ copy algorithm to copy a string literal, (instead of memcpy) but I'm getting segmentation fault I don't know why though. here is the code:
#include <iostream>
#include <cstring>
#include <stdio.h>
using namespace std;
int main(int argc, char *argv[]) {
// if using copy with regular pointers, there
// is no need to get an output iterator, ex:
char* some_string = "this is a long string\n";
size_t some_string_len = strlen(some_string) + 1;
char* str_copy = new char(some_string_len);
copy( some_string, some_string + some_string_len, str_copy);
printf("%s", str_copy);
delete str_copy;
return 0;
}
Fix :
char* str_copy = new char[some_string_len];
^ notice square bracket
Free memory using :
delete [] str_copy;
Related
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char const *argv[])
{
int i=0;
string s1 = "";
s1[i++]='F';
s1[i++]='U';
s1[i++]='A';
s1[i++]='A';
s1[i++]='D';
cout << s1;
return 0;
}
You're trying to modify elements in an empty string.
If you want your code to work there are several ways to do this:
add elements to s1, you can use s1 += 'A' or s1.push_back('A') instead.
Allocate enough space to modify each element by doing s1.resize(5) after string s1 = "";.
And possibly more, but that should get you started. Think of std::string as an array of characters. If your array is empty, you either have to resize it or add things to it.
Note: Don't use #include <bits/stdc++.h> just do #include <string>.
Note: Avoid using using namespace std;
s1 is empty, any indexing into it will be out of bounds and lead to undefined behavior. Do e.g. s1 += 'F' instead. – Some programmer dude
Using the strcpy_s() function I want to collate the first three strings into the final one to print my full name. This is what I have and it doesn't work as I'm using char* strings and not std::strings.
#include <iostream>
using namespace std;
int main()
{
char str_first[] = "Nerf_";
char str_middle[] = " Herder";
char str_last[] = "42";
char str_fullName[35];
strcpy_s(str_fullName, (str_first + str_middle + str_last).c_str());
cout << str_fullName;
}
Any suggestions?
This should be close to what you're looking for, strictly using strcpy_s to concatenate strings together:
#include <string.h>
#include <iostream>
using namespace std;
int main()
{
char str_first[] = "Nerf_";
char str_middle[] = " Herder";
char str_last[] = "42";
char str_fullName[35];
int index = strcpy_s(str_fullName, sizeof str_fullName, str_first);
index += strcpy_s(str_fullName + index, sizeof str_fullName - index, str_middle);
index += strcpy_s(str_fullName + index, sizeof str_fullName - index, str_last);
cout << str_fullName;
}
The index variable serves a couple of purposes: (1) to provide a new index into the output str_fullName string as the string is built, and (2) subtracted from sizeof str_fullName, it "adjusts" the available buffer size as the string is built.
Caveats are that you should add overflow checking via the output from strcpy_s, and (as noted by others) there are better patterns to follow for doing this, but probably as an academic exercise there's something good to be learned here.
You need to use both strcat and strcpy
See code comments for more info.
// disable SDL warnings in Visual studio
#define _CRT_SECURE_NO_WARNINGS
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
// TODO: insert checking code,
// to make sure destination can hold all characters + one termination.
char str_first[] = "Nerf_";
char str_middle[] = " Herder";
char str_last[] = "42";
char str_fullName[35];
// copy first string because we need null terminated destination
strcpy(str_fullName, str_first);
// append the rest, string is auto null terminated.
strcat(str_fullName, str_middle);
strcat(str_fullName, str_last);
cout << str_fullName;
}
If I am not mistaken the function strcpy_s expects three arguments. So either supply one more argument to the function call or use instead the function strcpy.
And there is no need to use the standard class std::string to perform the task.
The code can look the following way
strcpy( str_fullName, str_first );
strcat( str_fullName, str_middle );
strcat( str_fullName, str_last );
Or you could use strcpy_s and strcat_s provided that you will specify the correct number of arguments.
Pay attention to that you need to include the header
#include <cstring>
I am trying to convert data into the right format for a specific unit test.
The task is to mine a set of words, the unit tests will make sure the results are correct. I have no access to the unit tests, just the declaration which takes a const char* const* Result.
So I need to get my
std::vector<string> Words;
to
const char* const* Result;
divided by a non-alpha char (for example space).
I am aware that this is a constant pointer to a constant character, so I am not sure what to do here since they both constant?
Any pointers (word pun not really intended) are appreciated!
You cannot meaningfully convert one to the other. However, you can convert an array of std::string into an array of pointers to char, and a pointer to the first element of such array would be compatible with your desired result:
std::vector<const char*> Ptrs;
std::transform(
std::cbegin(Words), std::cend(Words),
std::back_inserter(Ptrs),
[](auto& str) { return str.c_str(); }
);
const char* const* Result = Ptrs.data();
Just remember that the strings themselves are still stored in the std::string objects and those pointers within the new vector are only valid as long as the strings in the original vector exist, aren't resized, and the original vector itself isn't resized.
And the pointer to first element of the new vector is only valid as long as that vector exists and isn't resized.
Seems easy enough
#include <algorithm>
#include <functional>
// ...
std::vector<char const*> result_owner(Words.size());
std::transform(begin(Words), end(Words), begin(result_owner),
std::mem_fn(&std::string::c_str));
const char* const* Result = result_owner.data();
Just because Result must provide a const view of the buffer, doesn't mean the buffer has to really be const itself. So it's just another vector that we obtain by projecting Words on the std::string::c_str member.
After that Result can simply be another reference to result_owner.data();.
This of course assumes that Result doesn't have to own the buffer it points at. Owning raw pointers are best avoided.
And the caveman way to do it :)
#include <iostream>
#include <vector>
#include <string>
#include <string.h>
using namespace std;
char **foo(const vector<string> &vec_of_strings)
{
int num_strings = vec_of_strings.size();
int max_str_len = 0;
for (int i=0;i<num_strings;i++)
{
if (max_str_len < vec_of_strings[i].length()) {
max_str_len = vec_of_strings[i].length();
}
}
// for null termination ...
max_str_len++;
char **result = (char **) malloc(num_strings);
for (int i=0;i<num_strings;i++)
{
result[i] = (char *) malloc(max_str_len);
strcpy(result[i],vec_of_strings[i].c_str());
}
return result;
}
int main(int argc, char **argv)
{
vector<string> vec_of_strings;
vec_of_strings.push_back("Long");
vec_of_strings.push_back("Livvvvvvvve");
vec_of_strings.push_back("The");
vec_of_strings.push_back("King");
const char * const * Result = foo(vec_of_strings);
for (int i=0;i<4;i++)
{
printf("%s\n",Result[i]);
}
}
I am using th following code but it only asks me for a input and closes without couting my input
#include <iostream>
#include <string>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main(){
int balance=0;
int withdraw=0;
char* str;
cin.getline(str,10);
cout<<str;
withdraw=atoi(strtok(str," "));
balance=atoi(strtok(NULL," "));
cout<<withdraw<<" "<<balance;
return 0;
}
char* str;
This only gives you a pointer. That pointer doesn't point anywhere, especially not at some chars that you can write to. When you call cin.getline(str,10), it tries to write to where this pointer is pointing to. That gives you undefined behaviour. An easy fix for this is to make str an array of 10 chars:
char str[10];
However, I recommend that you start using std::string instead and figure out how to do strtok-like operations with a std::string. Hint: look at std::istringstream.
You need to allocate memory for str.
char *str = new char[10];
otherwise using uninitialized pointer will invoke undefined behavior. And call delete to free the allocated memory once you done with str.
delete[] str;
Instead of using char *, it is better to use std::string.
I am new to c++ and doing some self training from a text book. I need to create a new class, "String". It must use a constructor to initialize the string to a made up of a repeating character of a sepcified length.
I cannot figure out how to assign anything to a char* variable. Per the assignment I CANNOT use the standard string library to do this. What Do I need to do in my constructor?
#include "stdafx.h"
#include <cstdlib>
#include <iostream>
#include <string.h>
using namespace std;
class String {
protected:
int _len;
public:
char *buff;
String (int n, char* c);
};
int main()
{
String myString(10,'Z');
cout << myString.buff << endl;
system("PAUSE");
return 0;
}
String::String(int n, char* c)
{
buff = new char[n];
}
You're almost there: since you need repeated character, you shouldn't be passing char*, just a plain char. Also buffers of C strings need to be longer by one character than the string; the last element of the buffer must be the zero character \0.
String::String(int n, char c) {
buff = new char[n+1];
for (int i = 0 ; i != n ; buf[i++] = c)
;
buf[n] = '\0';
}
Note that making buf a public member variable is not a good idea: users of String shouldn't be able to reassign a new buffer, so providing an accessor char* c_str() and making buf private is probably a good idea.