When I create something like
char* t = new char[44];
t = strcpy(s,t);
then strlen(t); return some wrong results. how I can change this?
Both strcpy and strlen expect to find the special character NUL or '\0' in the array. An uninitialized array, as the one you've created, may contain anything at all, which means the behavior of your program is undefined when it is passed to strcpy as the source argument.
Assuming the goal was to copy s into t, to make the program behave as expected, try this:
#include <iostream>
#include <cstring>
int main()
{
const char* s = "test string";
char* t = new char[44];
// std::strcpy(t, s); // t is the destination, s is the source!
std::strncpy(t, s, 44); // you know the size of the target, use it
std::cout << "length of the C-string in t is " << std::strlen(t) << '\n';
delete[] t;
}
But keep in mind that in C++, strings are handled as objects of type std::string.
#include <iostream>
#include <string>
int main()
{
const std::string s = "test string";
std::string t = s;
std::cout << "length of the string in t is " << t.size() << '\n';
}
What are you trying to do? Do you want to copy from s to t? If so, the arguments to strcpy are reversed.
char* t = new char[44]; // allocate a buffer
strcpy(t,s); // populate it
Such C-style string processing is a red flag, but that's all I can say given this little information.
This code might be helpful:
char * strcpy (char * destination, const char * source);
t = strcpy(t, s);
You have to initialize the variable t
Do something like this:
char *t = new char[44];
memset(t, 0, 44);
// strlen(t) = 0
The strcpy function is described thus:
#include <string.h>
char *strcpy(char *dest, const char *src);
The strcpy() function copies the string pointed to by src (including the terminating '\0' character) to the array pointed to by dest.
So, if you are trying to fill in your newly allocated array, you should be doing:
strcpy(t, s);
Not the other way around.
Related
I have a char pointer:
char* s = new char[150];
Now how do i fill it? This:
s="abcdef";
Gives warning about deprecation of conversion between string literal and char*, but generally works.
This:
char* s = new[150]("abcdef");
Does not work, gives an error.
How to do this properly? Note that I want the memory allocation to have 150*sizeof(char) bytes and contain "abcdef". I know about malloc, but is it possible to do with new?
Its for an assignment where i cant use the standard library.
This sequence of statements
char* s = new char[150];
s="abcdef";
results in a memory leak because at first a memory was allocated and its address was assigned to the pointer s and then the pointer was reassigned with the address of the string literal "abcdef". And moreover string literals in C++ (opposite to C) have types of constant character arrays.
If you allocated a memory for a string then you should copy a string in the memory either by using the C standard function strcpy or C standard function strncpy.
For example
char* s = new char[150];
std::strcpy( s, "abcdef" );
Or
const size_t N = 150;
char* s = new char[N];
std::strncpy( s, "abcdef", N );
s[N-1] = '\0';
Or even the following way
#include <iostream>
#include <cstring>
int main()
{
const size_t N = 150;
char *s = new char[N]{ '\0' };
std::strncpy( s, "abcdef", N - 1 );
std::cout << s << '\n';
delete []s;
}
In any case it is better just to use the standard class std::string.
std::string s( "abcdef" );
or for example
std::string s;
s.assign( "abcdef" );
The basic procedure for creating a memory area for a string and then filling it without using the Standard Library in C++ is as follows:
create the appropriate sized memory area with new
use a loop to copy characters from a string into the new area
So the source code would look like:
// function to copy a zero terminated char string to a new char string.
// loop requires a zero terminated char string as the source.
char *strcpyX (char *dest, const char *source)
{
char *destSave = dest; // save copy of the destination address to return
while (*dest++ = *source++); // copy characters up to and including zero terminator.
return destSave; // return destination pointer per standard library strcpy()
}
// somewhere in your code
char *s1 = new char [150];
strcpyX (s1, "abcdef");
Given a character array:
char * s = new char [256];
Here's how to fill the pointer:
std::fill(&s, &s + sizeof(s), 0);
Here's how to fill the array:
std::fill(s, s+256, '\0');
Here's how to assign or copy text into the array:
std::strcpy(s, "Hello");
You could also use std::copy:
static const char text[] = "World";
std::copy(text, text + sizeof(text), s);
Remember that a pointer, array and C-Style string are different concepts and objects.
Edit 1: Prefer std::string
In C++, prefer to use std::string for text rather than character arrays.
std::string s;
s = "abcdef";
std::cout << s << "\n";
Once you've allocated the memory for this string, you could use strcpy to populate it:
strcpy(s, "abcdef");
I have the following stupid snippet:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
const string classpath = "Hello Dolly!";
const int len = classpath.length()+1;
char str[len];
strncpy(str, classpath.c_str(), len);
cout << str << endl;
return 0;
}
The aim ist to assign a c++ string to a c char array. The string is known at compile time, hence a constant. But the string may vary from one project to an other. I have no intention to count chars for the compiler. Hence the const len should be computed at compile time as shown. This works with cygwin and on linux. But the visualstudio compiler sees a problem and gives me the error C2131!
How to work around?
(Please consider I'm a Java programmer being troubled loosing time on such kind of problems!)
In C++ array sizes must be known at compile time.
You can dynamically allocate contiguous memory during run-time by using operator new:
char * my_array = new char[length];
Remember to use the delete[] to free up the memory after you are finished with it.
Also, C-style arrays need that terminating nul character so you will need to allocate one extra slot in the array.
To copy a std::string to a character array:
const std::string example = "example";
const std::string::size_type length = example.length();
char * p_array = new char [length + 1];
strcpy(p_array, example.c_str());
cout << p_array << endl;
delete[] p_array;
I have a function like this:
template <typename T>
void parse_to_T(const std::string& str, T* result) {
std::stringstream ss;
ss << str;
ss >> *result;
}
this function is mean to convert the string to the specified type.
it is work to parse the string to int, float or char.
parse_to_T<int>(...);
parse_to_T<float>(...);
parse_to_T<char>(...);
but when meet char*, segment fault ...
I use the function like this:
int int_val;
string m = "1";
parse_to_T<int>(m, &int_val); // works
char* str_val = NULL;
parse_to_T<char*>(m, &str_val); // segmentfault
How to imply this function to make it work?
(convert the string to specified type like int, double, char, char*)?
Hey, I don't know how to explain my use case, but I will try:
To simple, the question is, given a file, for each line, data may have these types :
int
float
char
char*
an array T[num] (T is int, float, char or char*, or any build_in type.)
imple a parse function to parse this file.
and this problem is an exam ...
thanks and I found the error now.
char* str_val = NULL;
parse_to_T<char*>(m, &str_val); // segmentfault;
char* str_val;
parse_to_T<char*>(m, &str_val); // segmentfault;
char* str_val = new char[256];
parse_to_T<char*>(m, &str_val); // works !!
then the error is I didn't allocate memory to the ptr...
This segfault is because stringstream does not allocate memory to hold the result of the operation when extracting values into a char* array. It tries to put the values into the memory pointed at by the lhs operand. You must allocate memory yourself.
Here is a simple example:
#include <string>
#include <sstream>
#include <iostream>
template <typename T>
void parse_to_T(const std::string& str, T* result) {
std::stringstream ss;
ss << str;
std::cout << ss.str() << std::endl;
ss >> *result;
std::cout << *result << std::endl;
}
int main() {
char* buffer = new char[256];
/* Don't do this in real code. If the input is larger than
the size of the buffer it will end very, very badly.
always have a way of allocating the correct amount
of memory.
*/
int int_val;
std::string m = "1";
parse_to_T<int>(m, &int_val);
char* str_val = NULL;
parse_to_T<char*>(m, &buffer);
delete[] buffer;
return 0;
}
You could include a template specialization for the char* datatype that does the allocation based on the amount of data in the stream (calling stringstream.str().size() should work) but the user would have to free the returned memory.
First, your destination variable str_val has no allocated memory, so it is normal you have a segmentation fault.
On the other hand, it would be better if you use std::string instead. If you need the raw pointer const char* then you can use std::string::c_str for so. If you have to modify it then just create a copy.
I am practicing some work with cstring and string.
Going from string to cstring using c_str() I get an incompatible data type compile error.
For example this is the code that gives said error:
string str = "StackOverFlow";
char inCstring[20]{};
inCstring = str.c_str();
Any ideas?
The problem is that str.c_str() returns a const char*, and you are trying to pass it to a char*. Use strcpy to get your expected result:
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
string str = "StackOverFlow";
char inCstring[20];
strcpy(inCstring, str.c_str());
cout << "str: " << str << endl;
cout << "inCstring: " << inCstring << endl;
return 0;
}
So I have figured out two ways to accomplish this.
First, it is important to remember that you can't assign to a whole array, meaning it is necessary to specify the element of the array to assign to. Attempting to assign a string to char array simply will not work for this reason. That being said, by specifying the element it would be possible to assign a character in a specific element of a char array. Below are two methods that accomplish a string to cstring(string to char array) "conversion". Please see answer by Vincent for complete code. I have found Method B better since I would like to have max size on my character array.
Method A:
string str = "StackOverFlow";
const char* inCstring;
inCstring = str.c_str();
Method B:
string str = "StackOverFlow";
char inCstring[20]{};
Then use strcpy
strcpy(inCstring, str.c_str());
I am not able to concat two const char*.
I do the following:
const char* p = new char[strlen(metadata.getRoot())+strlen(metadata.getPath())];
strcat(const_cast<char*>(p),metadata.getRoot());
strcat(const_cast<char*>(p),metadata.getPath());
strcpy(const_cast<char*>(args2->fileOrFolderPath),p);
function(args2->fileOrFolderPath);
Now when I print the variable args2->fileOrFolderPath on the console then the correct output appears... But when I call a method with the variable as parameter, and work with the variable then I got a segmentation fault. What is the problem?
I did not declare them like this but i know they have this information
So, I have this:
const char* ruta1 = "C:\\Users\\Deivid\\Desktop\\";
const char* ruta2 = "lenaGris.xls";
Then I used this for concatenation:
char * RutaFinal = new char[strlen(ruta1) + strlen(ruta2) + 1];
strcpy(RutaFinal, ruta1);
strcat(RutaFinal, ruta2);
printf(RutaFinal);
This worked for me.
I would prefer using std::string for this, but if you like char* and the str... functions, at least initialize p before using strcat:
*p = 0;
BTW:
using std::string, this would be:
std::string p = std::string(metadata.getRoot()) + metadata.getPath();
strcpy(const_cast<char*>(args2->fileOrFolderPath), p.c_str());
function(args2->fileOrFolderPath);
And you don't have to deallocate p somewhere.
1.
const char* p=new char[strlen(metadata.getRoot())+strlen(metadata.getPath())+1];
the length plus 1 to store '\0'.
2.
strcpy(const_cast<char*>(args2->fileOrFolderPath),p);
You can not guarantee args2->fileOrFolderPath 's length is longger than strlen(p).
This works well
#include <iostream>
using namespace std;
void foo(const char*s){
cout<<s<<endl;
}
int main(int argc,char*argv[]){
const char* s1 = "hello ";
const char* s2 = "world!";
const char* p = new char [strlen(s1)+strlen(s2)+1];
const char* s = new char [strlen(s1)+strlen(s2)+1];
strcat(const_cast<char*>(p),s1);
strcat(const_cast<char*>(p),s2);
strcpy(const_cast<char*>(s),p);
cout<<s<<endl;
foo(s);
return 0;
}
You have char pointers, pointing to char constants which can't be modified . What you can do is to copy your const char array to some char array and do like this to concate const strings :
char result[MAX];
strcpy(result,some_char_array); // copy to result array
strcat(result,another_char_array); // concat to result array
I believe you need to include space for the null terminator, and the first parameter to strcat shouldn't be const as you're trying to modify the memory being pointed to.
You want to do something like this:
char * str1 = "Hello, ";
char * str2 = "World!\n";
char * buffer = malloc(strlen(str1) + strlen(str2) + 1);
strcpy(buffer, str1);
strcat(buffer, str2);
printf(buffer);
Which prints out "Hello, World!" as expected.
As for the error you're seeing when using a parameter, I've wrote some tests to see why it doesn't break when using a const local variable. While compiling using a const char * for the pointer I'm using as the target I get this warning:
./strings.c:10: warning: passing argument 1 of ‘strcat’ discards qualifiers from pointer target type
As it states, const is discarded and it works as expected. However, if I pass a parameter which is a const char * pointer, then I get a bus error when trying to modify the buffer it writes to. I suspect what is happening is that it ignores the const on the argument, but it can't then modify the buffer because it's defined as const elsewhere in the code.