C++ passing char array to function - c++

I would rather just use a string, but we aren't supposed to as the teacher hates them and wants us to figure out ways to avoid them. So I looked into using a struct, but we aren't that far in the book and she hates it when I skip ahead. So I was thinking of doing this:
#include <iomanip>
#include <iostream>
#include <stdio.h>
using namespace std;
void myfunc(char& );
int main()
{
char myname[12];
cout<<"enter a name ";
cin>>myname;
cout<<"myname is "<<myname;
cout<<"myname is " << myfunc(myname);
getchar();
getchar();
return 0;
}
void myfunc(char &myname1)
{
myname1 = "Billy"
}
But this doesn't work and I don't know why.

One way is to do it like this:
void myfunc(char *myname1)
{
strcpy(myname1,"Billy");
}
You will also need to change your main to:
myfunc(myname);
cout<<"myname is " << myname;
However you have to be careful not to overflow your initial buffer.
The reason why your original code doesn't work is because you can't assign strings to char pointers. Instead you must copy the string to the char*.

This line of code is wrong:
cout<<"myname is " << myfunc(myname);
myfunc() doesn't return anything, its return type is void.
Try using:
char* myfunc(char *myname1)
{
strcpy(myname1,"Billy");
return myname;
}
Or
myfunc(myname);
cout<<"myname is " << myname;

Arrays devolve into pointers when passed as parameters.
So the simple way that you want is:
char* myfunc(char* myname1)
{
return myname1;
}
If you were going to show off you can pass the array by reference.
But if you can't read ahead you will not be able to use this.
char* myfunc(char (&myname1)[12]) // Note you can only pass arrays of size 12
{ // to this function so it is limited in use.
return myname1;
}
TO make it more useful though you could template it:
template<int SIZE>
char* myfunc(char (&myname1)[SIZE])
{
return myname1;
}

myname1 = "Billy" doesn't copy a string it copies a pointer to the constant local memory containing "Billy"
Take a look at strncpy() or memcpy()

Pass it as a char* instead of a char&. You're passing a reference to a single character instead of a pointer to a character array in this code.
Also use strncpy (google it) to set the value of tr char* once you're in the function.

void myfunc(char& ); is the problem it should take in a char * and not a char reference which is what you did.
and in the function use strcpy(char * destination, char *source);

Related

return char array from function that passes parameters

I'm working with a piece of C++ code that reads lines from a txt file and then assign each line to to an array called lines. Then it calls a function that converts each element in the lines array to a char array and then return the resulted char array. This step is where I stuck. How could I return a char array from the function toChar and assign the returned array to another array so I can use it as I need? (the rest of the code should use each returned char array to write it in a pipe, this not important right now but just to clarify why I need to learn to return an array from a function)
Here is the code I'm using:
#include <fstream>
#include <iostream>
#include <string.h>
#include <unistd.h>
#include <cstdlib>
using namespace std;
char * toChar(string line);
int main()
{
string lines[0] = "line1";
char* a = toChar(lines[0]);
return 0;
}
char * toChar(string line)
{
char a[1024];
strcpy(a, line.c_str());
return a;
}
Please note that in this code I'm trying to shrink the code so I'm assigning a simple string value to the array
when I try to compile this code, the error below appears:
warning: address of local variable 'a' returned
any help or suggestion is greatly appreciated..
First use a const & in passing the string to the function to avoid the unnecessary copying, and be able to use temporaries, e.g. toChar("I am temp");
The are the following alternatives:
(1) Return std::string
std::string toChar(std::string const & line)
{
char a[1024];
strcpy(a, line.c_str());
return a;
}
Of course it is assumed that line is smaller than 1024 chars with the null termination symbol
(2) Return an allocated array the
char * toChar(std::string const & line)
{
char * a = new char[1024];
strcpy(a, line.c_str());
return a;
}
but you will have to actually manage it and delete it later.
(3) Allocate the array and pass it to the function
void toChar(string const & line, char a[])
{
strcpy(a, line.c_str());
}
I imagine that you actually want to extract a C-string from an std::string , or some part of it. The proper way to do it is (3).
The warning is correct and practically is an error. You're declaring the char array locally so it will be deleted after going out of scope of that function and its address will be no more valid.
Since you're using c++ avoid char array and use a std::string.
If you want to access to the internal storage of your string you can call line.c_str() which returns a const char *.
Hence you won't need you function toChar that creates a local array that will go out of scope at the end of your function.
You could simply do :
int main()
{
string lines[0] = "line1";
const char* a = lines[0].c_str();
return 0;
}
But I advise you to keep manipulating std::string as they will handle string better than a simple char *.
And if you want a copy, just do it : std::string mycopy = lines[0].

Understanding pointers used for out-parameters in C/C++

How do I return a char array from a function?
has the following code in the answers:
void testfunc(char* outStr){
char str[10];
for(int i=0; i < 10; ++i){
outStr[i] = str[i];
}
}
int main(){
char myStr[10];
testfunc(myStr);
// myStr is now filled
}
Since I will be using an Arduino where memory is precious I dont want a "temporary variable" for storing some string and then copying it over. I also don't want the function to return anything. I want to use the idea above and do something like:
void testfunc(char* outStr){
outStr="Hi there.";
}
int main(){
char myStr[10];
testfunc(myStr);
}
However, in this case myStr is empty!
Why doesn't this work? How do I fix it?
(I'm relatively new to C, and do have a basic understanding of pointers)
Thanks.
Why doesn't this work?
void testfunc(char* outStr){
outStr="Hi there.";
}
You have:
testfunc(myStr);
When testfunc is called, outStr is assigned the address of the first element of myStr. But in the testfunc function, you overwrite outStr and it now points to a string literal. You are only modifying ouStr, not myStr.
How do I fix it?
To copy a string, use strcpy function (or its secure sister strncpy):
void testfunc(char* outStr){
strcpy(ouStr, "Hi there.");
}
If you want memory reuse - and this is a dangerous place, has you must take really good care about allocation/deallocation responsibility, you should use pointer to string, ie:
#define STATIC_STRING "Hi there"
void testfunc(char**outStr){
*outStr=STATIC_STRING;
}
int main(){
char*myStr;
testfunc(&myStr);
//From now on, myStr is a string using preallocated memory.
}

How do I assign a char* to a char array?

Compiler tell me "incompatibles type in assignments of char* to char[32]"
this is my code:
char* generalOperations[2]={"Off","On"};
void test(){
char value[32];
switch(swapVariable){
case 0:
value=generalOperations[0]; //<==Error HERE!
break;
}
}
[Solved]:
strcpy(value,generalOperations[0]);
Use std::string instead of char* and std::array<T, N> instead of T[N]. Both are type safe (as opposed to memcpy), both are in modern C++ style and both are directly assignable using the assignment operator.
#include <array>
#include <string>
std::array<std::string, 2> generalOperations{"Off", "On"};
void test() {
std::string value;
switch(swapVariable) {
case 0: value = generalOperations[0]; break;
}
}
You can't assign arrays. You can either change the type of value to a char* or copy the content of generalOptions[0] into value. If you are going to copy the content, then you need to ensure that value has enough space to hold the content of the element in generalOperations.
Modifying a string literal is undefined behaviour, by changing the type to const char* the compiler can detect any attempt to modify one of the entries in generalOperations instead of experiencing odd behaviour at runtime:
const char* generalOperations [2]={"Off","On"};
const char* value;
Note you don't have to specify the number of elements in the array if you are initialising it:
const char* generalOperations [] = {"Off","On"};
Or, if this really is C++ you can make value a std::string instead and just assign to it which will copy the generalOperations element.
As C++ appears to really be the language and C++11 features are permitted instead of using a switch you could create a std::map that associates the int values with the std::string:
#include <iostream>
#include <string>
#include <map>
const std::map<int, std::string> generalOperations{ {17, "Off"},
{29, "On" } };
int main()
{
auto e = generalOperations.find(17);
if (e != generalOperations.end())
{
// Do something with e->second.
std::cout << e->second << "\n";
}
return 0;
}
Demo: http://ideone.com/rvFxH.
#include <string.h>
...
strcpy(value, generalOptions[0]);
You cannot assign arrays in C/C++. There are functions do to that for you. If your char array represents a C style string (i.e. a null terminated sequence of characters), then there are more specialist functions for that as well. strcpy is one of those functions.
Your assignment is wrong, since you cannot assign a char * to char array instead of using this assignment you can use strcpy().

Function argument, const char **, Temp Variable

I want to pass an argument to a function, which takes a const char **
#include<iostream>
using namespace std;
void testFunc(const char **test){}
string testString = "This is a test string";
int main()
{
const char *tempC = testString.c_str();
testFunc(&tempC);
return 0;
}
This code works fine, But I dont want to go through the temporary variable tempC. I want to pass testString.c_str() directly. Like the following,
int main()
{
testFunc(&testString.c_str());
return 0;
}
But, it shows error,
error C2102: '&' requires l-value
Is it possible to do it without using the temp variable.
I want to pass testString.c_str() directly.
You can't. std::string::c_str() returns a const char *. In order to make a pointer to a string, you have to put it in a variable and take its address.
That being said, I'm far more concerned about what function you're trying to pass this to. In general, a function that takes a const char ** does so for two reasons:
1: It takes an array of strings. You are passing a single string. Usually, C-style functions that take an array need a second parameter that says how many elements are in the array. I hope you're putting a 1 in there.
2: It is returning a string. In which case what you're doing is not helpful at all. You should create a const char * as a variable, initialize it to NULL, and then pass a pointer to it as the parameter. It's value will be filled in by the function.
You're going to need two temp variables to call glShaderSource, so you might as well wrap them up in one function that takes the string directly.
#include <gl.h>
#include <string>
void setShaderFromString(std::string &instr, GLuint shader)
{
const GLchar *str[1]; // room for one const GLchar *
GLint len[1]; // make this an array, for symmetry
str[0] = instr.c_str();
len[0] = instr.length();
glShaderSource(shader, 1, str, len);
}
Simply - no.
(filling up some space)
You can also do type-casting:
int main()
{
testFunc((const char **)&testString);
return 0;
}

Pass a string in C++

Quick probably obvious question.
If I have:
void print(string input)
{
cout << input << endl;
}
How do I call it like so:
print("Yo!");
It complains that I'm passing in char *, instead of std::string. Is there a way to typecast it, in the call? Instead of:
string send = "Yo!";
print(send);
You can write your function to take a const std::string&:
void print(const std::string& input)
{
cout << input << endl;
}
or a const char*:
void print(const char* input)
{
cout << input << endl;
}
Both ways allow you to call it like this:
print("Hello World!\n"); // A temporary is made
std::string someString = //...
print(someString); // No temporary is made
The second version does require c_str() to be called for std::strings:
print("Hello World!\n"); // No temporary is made
std::string someString = //...
print(someString.c_str()); // No temporary is made
You should be able to call print("yo!") since there is a constructor for std::string which takes a const char*. These single argument constructors define implicit conversions from their aguments to their class type (unless the constructor is declared explicit which is not the case for std::string). Have you actually tried to compile this code?
void print(std::string input)
{
cout << input << endl;
}
int main()
{
print("yo");
}
It compiles fine for me in GCC. However, if you declared print like this void print(std::string& input) then it would fail to compile since you can't bind a non-const reference to a temporary (the string would be a temporary constructed from "yo")
Well, std::string is a class, const char * is a pointer. Those are two different things. It's easy to get from string to a pointer (since it typically contains one that it can just return), but for the other way, you need to create an object of type std::string.
My recommendation: Functions that take constant strings and don't modify them should always take const char * as an argument. That way, they will always work - with string literals as well as with std::string (via an implicit c_str()).
print(string ("Yo!"));
You need to make a (temporary) std::string object out of it.
For easy stuff like printing, you can define a sort of function in your preprocessors like:
#define print(x) cout << x << endl
The obvious way would be to call the function like this
print(string("Yo!"));
Make it so that your function accepts a const std::string& instead of by-value. Not only does this avoid the copy and is therefore always preferable when accepting strings into functions, but it also enables the compiler to construct a temporary std::string from the char[] that you're giving it. :)
Just cast it as a const char *.
print((const char *)"Yo!") will work fine.