Returning an array as a pointer - c++

I'm trying to use a separate function to read a few data values in from a file; I'm getting two errors (I haven't used c++ in a long time...):
double * FREAD(std::string fpath){
std::string line;
double * params = new double[14];
std::ifstream parameters (fpath);
if (parameters.is_open())
{
for (int b = 0; b < 14; b++) {
parameters >> line >> params[b];
}
}
parameters.close();
return params;
}
throws
error C2556: 'double *FREAD(std::string)' : overloaded function differs only by return type from 'double FREAD(std::string)'
and
error C2040: 'FREAD' : 'double *(std::string)' differs in levels of indirection from 'double (std::string)'
The second issue is thrown from the line where I call the function in main.
double * param = FREAD(parampath);
error C2440: 'initializing' : cannot convert from 'double' to 'double *'
If I don't define param as a value pointed at by a double, I get the same type mismatch error in reverse...
My understanding is that I'm supposed to return a pointer which is directed at the first value of the array my subfunction has created and use that to work with the data. But I can't seem to pull this value when I call the function in main.

The simplest and fool-proof way to do it would be to return a container, for example
#include <array>
std::array<double,14> FREAD(const std::string& fpath)
{
std::string line;
std::array<double, 14> params;
// .... fill params
return params;
}
Concerning the overload error, you cannot overload a function by return type. It looks like the compiler is seeing these two declarations:
double * FREAD(std::string fpath);
double FREAD(std::string fpath);
Given the above suggestion, you should remove both of them anyway.

Your error C2556 is because you apparently have another FREAD() function that returns something else. The error is telling you that you can't overload functions based only on the return type.
Going from the messages, it appears to me that you have two functions:
double * FREAD(std::string fpath)
double FREAD(std::string fpath)
You only posted the first one.
C++ only allows you have two functions with the same name if they take different arguments (or const-ness for member functions). You should either give your functions different names, or pass in a token argument that the compiler can use to tell which one you want.

Related

Conversion of std:string to char* [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 2 years ago.
Improve this question
I'm trying to convert a result string that I get by doing some data manipulation, eg:
std::string result = std::string(/* num_max */, '0').append(myDataModule->getId().c_str());
I'm getting an id from getId() (which returns an AnsiString) on my TDataModule, converting that to a std::string using AnsiString::c_str(), and appending that with zeros on the left (spaces that will remain) to my result string.
I need to use the value of result in a function that receives a char *:
void receiver(char * data, int num){
... <- A lot of code here
if( data != NULL )
{
strcpy( rdData, data); <-- rdData is an char *
...
}
}
Basically, in this function it will copy data to rdData and do some verifications.
When I run the code, an error appears when I call this function:
candidate function not viable: no known conversion from 'std::string' (aka 'basic_string') to 'char *' for 1st argument
When I run the code, an error appears when I call this function:
candidate function not viable: no known conversion from 'std::string' (aka 'basic_string') to 'char *' for 1st argument
You did not show the actual code that is trying to pass the std::string to the receiver() function, but the error message is very clear. You simply cannot assign a std::string directly to a non-const char*, which is exactly what the compiler is complaining about.
However, you can get a const char* from a std::string using its c_str() method, and then you can const_cast that to a char* (as long as the function does not try to modify the char data), eg:
std::string result = ...;
receiver(const_cast<char*>(result.c_str()), static_cast<int>(result.size()));
Or, you can simply use &result[0] instead (which is guaranteed in C++11 and later to be contiguous and null-terminated), or you can use result.data() in C++17 and later, eg:
std::string result = ...;
receiver(&result[0]/*result.data()*/, static_cast<int>(result.size()));
Or, you could simply change result from std::string to AnsiString, as its c_str() method returns a non-const char*, eg:
AnsiString result = AnsiString::StringOfChar('0', 8) + myDataModule->getId();
receiver(result.c_str(), result.Length());
Either way, if receiver() only needs to read from data and not modify its content, then it should be changed to take data as a const char* instead (especially since that is what strcpy() expects anyway), eg:
void receiver(const char * data, int num)
Then you can use result.c_str() as-is, no trickery, whether result is an AnsiString or a std::string.

C++ convert std::string to char

I have following scenario:
struct MyStruct
{
char name[25];
char address[12];
}
Somewhere::SomeMethod(std::shared_ptr<SomeArgumentClass> args)
{
// GetName() and GetAddress() both return std::strings
::MyStruct newValue = {args->GetName(), args->GetAddress()};
// add newValue to some structure that needs to have chars
}
Error:
error C2440: 'initializing' : cannot convert from 'std::string' to 'char'
error C2440: 'initializing' : cannot convert from 'std::string' to 'char'
I am not able to get my std::string converted to a char.
Thanks a lot!
Firstly, your terminology is incorrect. You don't want to convert to char, which is a single character. I realise that the error message claims you're trying to convert to char, but that's because your incorrect code has confused the compiler into thinking you're trying to initialise individual elements of the array name. Be wary of the specifics of an error message when you write the wrong code, because the compiler cannot read your mind — it can only go off of what you've written!
In reality you want to copy the characters inside your std::string, into the array of char, that is your member.
Like so:
Somewhere::SomeMethod(std::shared_ptr<SomeArgumentClass> args)
{
const auto& name = args->GetName();
const auto& address = args->GetAddress();
::MyStruct newValue;
std::copy(std::begin(name), std::end(name), &newValue.name[0]);
std::copy(std::begin(address), std::end(address), &newValue.address[0]);
// add newValue to some structure that needs to have chars
}
But you need to add bounds checking too. To do that, roughly I might consider replacing each std::copy call with something like:
std::copy_n(
&name[0],
std::min(name.size(), sizeof(newValue.name)),
&newValue.name[0]
);
You'll also need some null termination depending on how many characters were copied.
Generally though the salient point is that you need to actually copy those characters because there is no one-step way to do it. It stems in part from how arrays can't be assigned-to, but also from the fact that their dimensions are part of the type which makes things more complicated.
If this seems like a pain in the arse, that's because it is — ideally you would stick with std::string across the board because it's far superior, and was specifically introduced to make it easier to handle arrays of char. You can still pass a const char* (or char*!) pointing to the string's data into a C API. Of course if ::MyStruct itself is a third-party C type, you have no choice but to do it the hard way.

C++ chart series name from variable

I have a vector vector<string> headers; and for each header I want to add a new series to a chart control.
But my code doesn't work:
for (int i = 0; i < headers.size(); i++){
DataVisual_V2::MainForm::chart_data->Series->Add(headers[i]);
}
It gives the error:
IntelliSense: function "System::Windows::Forms::DataVisualization::Charting::SeriesCollection::Add" cannot be called with the given argument list
argument types are: (std::string)
object type is: System::Windows::Forms::DataVisualization::Charting::SeriesCollection
Any idea what could be the problem?
thanks
Benjamin
This function expects a parameter of System::String type, not std::string. System::String has a constructor that takes char*, so you can use
DataVisual_V2::MainForm::chart_data->Series->Add(String(headers[i].c_str()));

When calling the function this error [Error] incompatible types in assignment of 'char' to 'char [40]'

I am returning the *res (which is value resultant string after concatenating strings) in the function. When I call this function and store the result in the char array then it gives me error [Error] incompatible types in assignment of 'char' to 'char [40]'
.I want to concatenate two strings in the function and return the concatenating string from function.Kindly help to solve to this problem
#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
char strConcat(char *,char *);
char input1[10],input2[12],resultantString[40];
cout<<"Enter the 1st String=";
cin.getline(input1,10);
cout<<"Enter the 2nd String=";
cin.getline(input2,10);
//faulty code
resultantString=strConcat(input1,input2);
cout<<resultantString;
}
// st1 means String1 and St2 means string2 which we want to concat.
char strConcat(char *st1,char *st2)
{
char *res;
while(*st1!='\0')
{
*res=*st1;
*st1++;
*res++;
}
while(*st2!='\0')
{
*res=*st2;
*st2++;
*res++;
}
*res='\0';
return *res;
}
First off, remove using namespace std;, it's a bad habit.
Next up, move the function declaration void strConcat(char *,char *); out of main and make it the same type as the definition, this is your error, you declare strConcat to return void first but then you define it to return char, the compiler still thinks it returns void and thus when you're trying to assign something to it the compiler complains.
Next up, make main return int, your current definition isn't valid.
Next, indent your code so not only the compiler can read it but other humans too.
And the most important tip here, remove all of those static-sized arrays and that homebrewed strCat function and use std::string and it's operator+ for concatenation.

Passing an [out] array to C++ function

I have a C++\CLI managed class method that takes an out array. I want to pass this out array to the underlying C++ function that takes a vector< char >&. This C++ functions fills the array with values.
bool MyLib::GetBits([Out] array<unsigned char>^ %bits)
{
MyCppClass->GetBits(bits); // ????
// ERROR: C2664: cannot convert from 'cli::array<Type> ^' to 'std::vector<_Ty> &'
}
'GetBits' is declared as MyCppClass::GetBits(vector<char> &bits);
Have you any reason to expect that array<unsigned char>^ %bits can be converted to vector<char> &bits?
You can try to modify MyCppClass, adding a member that returns a reference to a static vector. In GetBits you can clear it, and iterate through bits adding the chars to it. You may also find Marshaling in C++ useful.