LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 03-11-2006, 06:18 AM   #1
pranavojha
Member
 
Registered: Feb 2006
Location: Bangalore, India
Distribution: Fedora Core 3
Posts: 68

Rep: Reputation: 15
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.

Last edited by pranavojha; 03-11-2006 at 06:19 AM.
 
Old 03-11-2006, 06:33 AM   #2
Nylex
LQ Addict
 
Registered: Jul 2003
Location: London, UK
Distribution: Slackware
Posts: 7,464

Rep: Reputation: Disabled
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.
 
Old 03-11-2006, 06:55 AM   #3
Flesym
Member
 
Registered: Aug 2005
Location: Germany
Distribution: Ubuntu, Debian
Posts: 189

Rep: Reputation: 31
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();

Last edited by Flesym; 03-11-2006 at 06:57 AM.
 
Old 03-11-2006, 07:18 AM   #4
pranavojha
Member
 
Registered: Feb 2006
Location: Bangalore, India
Distribution: Fedora Core 3
Posts: 68

Original Poster
Rep: Reputation: 15
Smile 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...
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.

Last edited by pranavojha; 03-11-2006 at 07:30 AM.
 
Old 03-11-2006, 08:33 AM   #5
Flesym
Member
 
Registered: Aug 2005
Location: Germany
Distribution: Ubuntu, Debian
Posts: 189

Rep: Reputation: 31
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

Last edited by Flesym; 03-11-2006 at 08:37 AM.
 
Old 03-11-2006, 09:08 AM   #6
pranavojha
Member
 
Registered: Feb 2006
Location: Bangalore, India
Distribution: Fedora Core 3
Posts: 68

Original Poster
Rep: Reputation: 15
i was hoping for an easier solution

too complex... there has to be a way around
thanx a lot

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

Last edited by pranavojha; 03-11-2006 at 09:09 AM.
 
Old 03-11-2006, 09:18 AM   #7
dmail
Member
 
Registered: Oct 2005
Posts: 970

Rep: Reputation: Disabled
Quote:
...too complex...
Ok give us an example of what you want to do with the chars.
 
Old 03-11-2006, 09:30 AM   #8
Flesym
Member
 
Registered: Aug 2005
Location: Germany
Distribution: Ubuntu, Debian
Posts: 189

Rep: Reputation: 31
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);
}
 
Old 03-12-2006, 12:24 AM   #9
pranavojha
Member
 
Registered: Feb 2006
Location: Bangalore, India
Distribution: Fedora Core 3
Posts: 68

Original Poster
Rep: Reputation: 15
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??

Last edited by pranavojha; 03-12-2006 at 12:47 AM.
 
Old 03-12-2006, 06:47 AM   #10
Flesym
Member
 
Registered: Aug 2005
Location: Germany
Distribution: Ubuntu, Debian
Posts: 189

Rep: Reputation: 31
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

Last edited by Flesym; 03-12-2006 at 08:18 AM.
 
Old 03-12-2006, 12:24 PM   #11
Crobat
Member
 
Registered: Dec 2005
Distribution: Slackware 10.2, Slackware 11.0
Posts: 135

Rep: Reputation: 15
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.

Last edited by Crobat; 03-12-2006 at 12:27 PM.
 
Old 03-12-2006, 01:10 PM   #12
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,011

Rep: Reputation: 110Reputation: 110
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.
 
Old 03-15-2006, 07:01 AM   #13
pranavojha
Member
 
Registered: Feb 2006
Location: Bangalore, India
Distribution: Fedora Core 3
Posts: 68

Original Poster
Rep: Reputation: 15
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...
 
Old 06-05-2008, 01:12 PM   #14
jonwatson
Member
 
Registered: Jun 2004
Location: Nova Scotia, Canada!
Distribution: Ubuntu
Posts: 170

Rep: Reputation: 30
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
 
Old 06-05-2008, 01:35 PM   #15
Nylex
LQ Addict
 
Registered: Jul 2003
Location: London, UK
Distribution: Slackware
Posts: 7,464

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


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Telling people to use "Google," to "RTFM," or "Use the search feature" Ausar General 77 03-21-2010 11:26 AM
bash cripting function to "identify" any char in a string? minike Programming 8 02-01-2006 09:45 AM
using java to find the location of the "\" char in a string caged Programming 8 02-03-2004 10:42 AM
<input type="button" disabled="true" > does not work in ns4.7 or 4.9 cybercop12us Programming 2 11-29-2002 08:31 AM
Cannot convert string "%s" to type %s jamaso Slackware 1 05-05-2002 04:06 AM


All times are GMT -5. The time now is 11:01 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration