LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How to convert "string" type to "char * " in c++ (https://www.linuxquestions.org/questions/programming-9/how-to-convert-string-type-to-char-%2A-in-c-423771/)

pranavojha 03-11-2006 06:18 AM

How to convert "string" type to "char * " in c++
 
I have been trying to write some codes on certain project that I am working on. I am not able to convert the datatype "string" to "char * " by using simple type cast,

Code:

string l="Pranav";
char *p;
p=(char *) l;

1. how do i convert string to char * type??
2. Is it possible to access the characters of a "string" in C++ one by one?

PS: I am using "g++" on my FD3 operating system.

Nylex 03-11-2006 06:33 AM

Quote:

Originally Posted by pranavojha
2. Is it possible to access the characters of a "string" in C++ one by one?

Not sure about your first question but for this one, yes. You can do it like you'd access the elements of an array. See the bottom of this page.

Flesym 03-11-2006 06:55 AM

In your sample let 'p' point to the address of the first char of string 'l':
Code:

string l="Pranav";
char *p;
p=&l[0];

As you can see it is possible, however, you have to be carful with this and in most cases you want to let 'p' be const, so you cannot break the inner string structure:
Code:

string l="Pranav";
const char *p;
p=l.c_str();


pranavojha 03-11-2006 07:18 AM

how to find the number of elements in a string array?
 
Quote:

Originally Posted by Flesym
In your sample let 'p' point to the address of the first char of string 'l':
Code:

string l="Pranav";
char *p;
p=&l[0];

As you can see it is possible, however, you have to be carful with this and in most cases you want to let 'p' be const, so you cannot break the inner string structure:
Code:

string l="Pranav";
const char *p;
p=l.c_str();


Thanx that helps.

i have another problem though... :newbie:
i have a program that accepts an array of string
int func(string pieces[ ])
how do i know how many elements in the array have been passed??
As far as i know "pieces[0].length()" gives the number of characters in a string. however "pieces.length()" doesn't work. plz help...
PS: I am not supposed to use an explicit argument for the number of values passed.

Flesym 03-11-2006 08:33 AM

Quote:

int func(string pieces[ ])
In C/C++ you cannot pass an array to a function. Actually this is the same like just using a pointer:
Code:

int func(string *pieces)
Also "pieces.length()" won't work, of course! In C++ (unlike Java) an array is no Object or Data Structure so it does not have any elements you may access with '.' The proper workaound of this is to use a second parameter that holds the length of the array:
Code:

int func(string *pieces, unsinged int length)
But this way you have to "trust" the user that he will call the function correctly..., and in most cases he won't. The best solution is to wrap the array into an object, encapsulate the data and use members to access them. But you aren't the first one who came across this problem, so you needn't to write this class by yourself, instead use "vector": This is part of the STL an will do what you want:
http://hea-www.harvard.edu/MST/simul...oc/Vector.html

pranavojha 03-11-2006 09:08 AM

i was hoping for an easier solution
 
too complex... there has to be a way around :scratch:
thanx a lot

------------------------------------------------------------------------
And they say that a hero can save us,
i'm not going to stand here and wait

dmail 03-11-2006 09:18 AM

Quote:

...too complex...
Ok give us an example of what you want to do with the chars.

Flesym 03-11-2006 09:30 AM

It really isn't very complex, here I worte a little program for you. All it does is building a string vector ("strings") and pass this to a function that will dump it.
Code:

#include <string>
#include <iostream>
#include <vector>

using namespace std;

typedef vector<string> vec2str;

void vecDump(vec2str strVec){
  strVec.push_back("last");
  for (int i = 0; i < strVec.size(); i++)
    cout << strVec[i] << " ";
}

int main(){
  vec2str strings;
  strings.push_back("frst");
  strings.push_back("second");
  strings.push_back("third");
  strings.push_back("fourth");
  strings[0]="first";
  vecDump(strings);
}


pranavojha 03-12-2006 12:24 AM

Quote:

Originally Posted by Flesym
It really isn't very complex, here I worte a little program for you. All it does is building a string vector ("strings") and pass this to a function that will dump it.

OK. Let me tell you what the problem is. Plz read carefully.

Problem Statement


In this problem we are going to make an 11x11 chess board out of the Cartesian plane. The positions on our board will be the coordinates (x,y) where

0 <= x <= 10,

0 <= y <= 10, and

x,y are integers.

We will consider two different chess pieces: rooks and bishops. A rook may move either horizontally or vertically. It may move any number of spaces in a straight line, so long as it does not run into another piece on the board. Each location that the rook can move to is considered 'under control'. A bishop is similar, except that it moves diagonally, instead of horizontally and vertically. For example, the following diagram shows the 11x11 board with one rook ('R') and one bishop ('B') where the locations under control are denoted by 'X':

Code:

. . X . . . . X . . .

 . . X . . . X . . . .

 X X R X X X X X X X X

 X . X . X . . . . . .

 . X X X . . . . . . .

 . . B . . . . . . . .

 . X . X . . . . . . .

 X . . . X . . . . . .

 . . . . . X . . . . .

 . . . . . . X . . . .

 . . . . . . . X . . .

You will be given a String[] pieces describing the locations of the rooks and bishops on the board. Each element will have the format (quotes for clarity) "x y P", where x and y are coordinates and P is Rook or Bishop. For example, "9 10 Rook" means there is a Rook at the position (9,10). Return the number of distinct positions that are collectively 'under control' by the given pieces. Note that the locations of the actual pieces should not be considered in the count. Hence, for the input above, you would return 27.

Definition

Class:

UnderControl

Method:

howMany

Parameters:

String[]

Returns:

int

Method signature:

int howMany(String[] pieces)
<- See why i dont want to use vector

(be sure your method is public)

Constraints

-

pieces will contain between 1 and 50 elements inclusive.

-

Each element of pieces will have the form (quotes for clarity) "x y P" where: x is an integer with no extra leading zeros between 0 and 10 inclusive, y is an integer with no extra leading zeros between 0 and 10 inclusive, and P is either Rook or Bishop.

-

No two pieces will be at the same location.

Examples

0){"0 0 Rook"}

Returns: 20

A rook in the lower left corner controls 20 squares. Each controlled square has the form (0,y) or (x,0) - with the exception of (0,0), which is the position of the rook.

1)
{"0 0 Bishop"}

Returns: 10

A bishop in the lower left corner only controls 10 squares.

2)
{"5 5 Bishop"}

Returns: 20

Near the center, the bishop controls more squares.

3)
{"0 5 Rook","2 5 Rook","5 5 Rook","9 5 Rook"}

Returns: 47

Many rooks sharing the same y-coordinate.

4)
{"0 0 Bishop","1 1 Rook"}

Returns: 20

The rook blocks the path of the Bishop.

5)
{"2 5 Bishop","2 8 Rook"}

Returns: 27


So what shud i do?
Heres my code, which doesn't compile (for the reasons Flesym pointed out),
Code:

#include<iostream>
#include<string>
#include<vector>
#define DELIM "\n\t\r "

using namespace std;

class UnderControl
{
 int arr[11][11];                /*array to store the valid positions*/
 int occupied[11][11];                /*array to store the places occupied by pieces*/
 public:                        /*1's represent possible pos occupied and 0's the vacant pos */
 UnderControl()                        /*Constructor*/
 {
 int i,j;
 for(i=0;i<11;i++)                /*Initialize all arrays to 0*/
  for(j=0;j<11;j++)
  {
  arr[i][j]=0;
  occupied[i][j]=0;
  }
 }
 int howMany(string pieces[]);        //The counter...
};

int UnderControl:: howMany(string pieces[])
{
 int count=0,i,j,k=0,x,y;
 char *b;
 
 while(k<pieces.size())      /*This the error thats been bugging me. How can i know the number of string sent?*/
 {
  const char *p = pieces[k].c_str();
  strcpy(b,p);
  b=strtok(b,DELIM);/*Seperating the X,Y positions and the piece name using strtok parser*/
  x=atoi(b);
  b=strtok(NULL,DELIM);//x
  y=atoi(b);
  b=strtok(NULL,DELIM);//y   
  occupied[x][y]=1;
  if(strcmp(tolower(b),"bishop")==0)
  {
  //going up...
  i=x-1;j=y-1;
  while(i>=0 && j>=0)
  {
    if(occupied[i][j]!=1)
    arr[i][j]=1;
    i--;j--;
  }
  //going down...
  i=x+1;j=y+1;
  while(i>=11 && j>=11)
  {
    if(occupied[i][j]!=1)
    arr[i][j]=1;
    i++;j++;
  }
  }
  else if(strcmp(tolower(b),"rook")==0)
  {
  for(i=0;i<11;i++)
    for(j=0;j<11;j++)
    if((i==x || j==y) && (occupied[i][j]!=1) )
      arr[i][j]=1;
  }
  else
  break;
  k++;
 }//while...
 for(i=0;i<11;i++)
  for(j=0;j<11;j++)                /*counting the possible positions.*/
  if(occupied[i][j]==0 && arr[i][j]==1 )/*According to prob the pos occupied by pieces shud not b considered.*/
    count++;
 return count;
}

int main()
{
 UnderControl u;
 string d[]={"0 0 rook","0 0 bishop"};
 int g=u.howMany(d);
 cout<<"Total = "<<g<<endl;
 cout<<endl;
 return 0;
}

Any suggestions??

Flesym 03-12-2006 06:47 AM

Ok, I haven't read the whole thing because I had a very long night with lots of beer and aren't able to understand anything today, but as I already said, you cannot pass an array to a function, but only the pointer to its first element! So you have to declare a second parameter with the size, or you use a struct or class that manages the data and size for you. Sorry, but there is no workaround! But as far as I can see, you can do it exactly like I showed you in my last post:
First define your own type, a vector of strings. This is not really necessary but it make things better readable:
Code:

typedef vector<string> vec2str;
Then change you function declaration and header to this:
Code:

class UnderControl{
//...
int howMany(vec2str pieces);        //The counter...
//...
}
int UnderControl::howMany(vec2str pieces)

And finally, don't use an array of strings, but the vector:
Code:

int main()
{
 UnderControl u;
 vec2str d;
 d.push_back("0 0 rook");
 d.push_back("0 0 bishop");
 int g=u.howMany(d);
 cout<<"Total = "<<g<<endl;
 cout<<endl;
 return 0;
}

In most cases you can use the vector very analog to a normal array. In example "d[2]" will access the third element. But a vector has many advantages, so it does not have a static size and may grow or shrink in its lifetime and much more. You don't even have to change your "error line" because the current size of a vector is accessed with (in your case) "pieces.size()".

Oh and one more general tip: In case, that in the original code the "UnderControl class" is declared in a header file (you should do this)then don't use the "using namespace" there! Have a look here:
http://nepsweb.co.uk/pgtcpp/namespace.htm

Crobat 03-12-2006 12:24 PM

Not sure why you'd want to change it into a C string, when there's a function to return the C string part of a string. Then you MIGHT be able to do something like this.

Code:

char *p;
strcpy(l.c_str(),p);

Check the order of the parameters in the strcpy function. They may be reversed.

I think that's it, if I remember correctly. :)

tuxdev 03-12-2006 01:10 PM

You have to allocate memory for the string first
Code:

char *p=new char[l.size()];
strcpy(l.c_str(),p);

l.c_str() returns a const char *, so you can't mess with the string. It also means it cannot be assigned to a non-const pointer.

pranavojha 03-15-2006 07:01 AM

why didn't i think of it..
 
Quote:

Originally Posted by Flesym
Ok, I haven't read the whole thing because I had a very long night with lots of beer and aren't able to understand anything today, but as I already said, you cannot pass an array to a function, but only the pointer to its first element! So you have to declare a second parameter with the size, or you use a struct or class that manages the data and size for you. Sorry, but there is no workaround! But as far as I can see, you can do it exactly like I showed you in my last post:
First define your own type, a vector of strings. This is not really necessary but it make things better readable:
Code:

typedef vector<string> vec2str;
Then change you function declaration and header to this:
Code:

class UnderControl{
//...
int howMany(vec2str pieces);        //The counter...
//...
}
int UnderControl::howMany(vec2str pieces)

And finally, don't use an array of strings, but the vector:
Code:

int main()
{
 UnderControl u;
 vec2str d;
 d.push_back("0 0 rook");
 d.push_back("0 0 bishop");
 int g=u.howMany(d);
 cout<<"Total = "<<g<<endl;
 cout<<endl;
 return 0;
}

In most cases you can use the vector very analog to a normal array. In example "d[2]" will access the third element. But a vector has many advantages, so it does not have a static size and may grow or shrink in its lifetime and much more. You don't even have to change your "error line" because the current size of a vector is accessed with (in your case) "pieces.size()".

Oh and one more general tip: In case, that in the original code the "UnderControl class" is declared in a header file (you should do this)then don't use the "using namespace" there! Have a look here:
http://nepsweb.co.uk/pgtcpp/namespace.htm


thanx that works... the vetors needn't be passed as args... whyu didn't i thought of it earlier...

jonwatson 06-05-2008 01:12 PM

This is me jumping on the bandwagon.

Can anyone explain to me why this doesn't compile? I can't figure it out for the life of me.
Code:

string mystring="testing";
char *p;
p=mystring.c_str();

g++ throws this when compiling:

Code:

error: invalid conversion from ‘const char*’ to ‘char*’
So confused....?

Thanks,

Jon

Nylex 06-05-2008 01:35 PM

c_str() returns a constant C-string. I suppose you could use strcpy() or strncpy() (cstring header) to do what you want.


All times are GMT -5. The time now is 12:28 AM.