Page 1 of 1
Substring in C++
Posted: Mon Sep 01, 2003 8:59 am
by fc34
Is there anyway to use a substring like function in C++?
for an example, i have an array with a filename
is there anyway to just return ".txt"?
Thank you!
Posted: Mon Sep 01, 2003 10:07 am
by sativa
well your syntax isn't correct in the first place. there should be single quotes for chars, also i see no array.
why dont you just include string.h or fstring.h ?
Posted: Mon Sep 01, 2003 10:39 am
by sativa
char fname[NUMLETTERS] = "example.txt"
in order to get the .txt part you'd have to know the # of elements in the array, then subtract 4.
for (int t=4;t>=0;t--)
cout<<fname[NUMLETTERS-t]
but if you want to do it with class string i forget how
Posted: Mon Sep 01, 2003 10:58 am
by Craig P.
#include <string>
// ...
std::string s = "example.txt";
std::string ext = (s.find('.') != std::string::npos) ? s.substr(s.find('.')+1) : "";
Not 100% sure about adding one to the result of find... double-check the documentation for find and substr (or I'll do it when I get a chance).
sativa, better to declare the array version as,
char s[] = "example.txt";
Or char const * s = "example.txt";
(since you're not modifying anything)
Posted: Tue Sep 02, 2003 12:33 am
by fc34
Ok, heres the code
char fname[20];
char efname[4];
cin<<fname
and then i wanna get the last 4 chars of fnaeme into efname
Posted: Tue Sep 02, 2003 5:23 am
by fc34
OK. I have changed the syntax to read
string fname;
void main(int argc, char **argv)
{
cin>>fname;
}
This works, but now, i cant copy argv[1] to fname. How can i do this if i define fname as a string instead of a char *fname?
Posted: Tue Sep 02, 2003 5:59 am
by Yahoolian
Do you want to replace fname with argv or just add argv to the end of the string fname?
Posted: Tue Sep 02, 2003 6:53 am
by fc34
basically, i want
fname = argv[1]
but this returns a 'cannot assign char * to string'
Posted: Tue Sep 02, 2003 7:52 am
by liquidsquid
Man, I need to learn C++, I am so used to C I have forgotten the ++ parts. I am assuming passing the filename as one of the arguments. This should extract the extension and copy it to a new char array, though this is from the top of my head.
If I were to do this in C:
#define MAX_EXT 4
void main(int argc, char **argv)
{
char fileExt[MAX_EXT];
short i;
//Look for the string starting point since we are doing a reverse lookup.
//Then go from the end of the string to the start looking for '.'
//Does not check for null string.
i = strlen(argv[0]); //Looks at only the first char string in the array of arguments, gets the end count of string
while(i > -1 && argv[0][i] != '.') i--; //Look for the first '.' in from end of string
if (i > -1) strcpy(fileExt, &(argv[0][i+1])); //Copy the extension only.
}
Not sure if it works, but you get the gist.
Posted: Tue Sep 02, 2003 7:56 am
by just brew it!
I don't know why it won't let you assign argv[1] to a string. The following program compiles and runs correctly under both Visual C++ 6.0 and GNU C++ 3.2:
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
if (argc < 2)
{
cout << "no argument specified\n";
return 1;
}
string fname = argv[1];
string efname;
int dot = fname.find_last_of('.');
if (dot != string::npos)
{
efname = fname.substr(dot);
cout << "Result = \"" << efname.c_str() << "\"\n";
}
else
cout << "no dot in argument\n";
return 0;
}
Posted: Tue Sep 02, 2003 8:59 am
by Craig P.
You also need to include <string> in jbi's code -- it's a library implementation feature that it worked without it.
Also, it shouldn't be necessary to insert using the c_str() member, you should be able to insert the string directly.
I agree that find_last_of is a better choice than find (which I used), but note that if you use the result directly, you'll pick up the '.' character.
Posted: Tue Sep 02, 2003 9:17 am
by just brew it!
Craig P. wrote:You also need to include <string> in jbi's code -- it's a library implementation feature that it worked without it.
Yeah, that makes sense. I tend not to use the C++ standard library all that much; the fact that it compiled OK with both VC++ and g++ led me to believe that it was not required. (Perhaps it is being included automatically by iostream?)
Also, it shouldn't be necessary to insert using the c_str() member, you should be able to insert the string directly.
Without the c_str() it compiles OK under g++, but gives a compilation error under VC++. (The error message is: "error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no acceptable conversion)"
)
Posted: Tue Sep 02, 2003 9:29 am
by fc34
Thank you!
My program works now
Posted: Tue Sep 02, 2003 9:34 am
by just brew it!
What was causing the 'cannot assign char * to string' error? (Just curious...)
Posted: Tue Sep 02, 2003 11:16 am
by Craig P.
just brew it! wrote:Also, it shouldn't be necessary to insert using the c_str() member, you should be able to insert the string directly.
Without the c_str() it compiles OK under g++, but gives a compilation error under VC++. (The error message is: "error C2679: binary '<<' : no operator defined which takes a right-hand operand of type 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' (or there is no acceptable conversion)"
)
Either <string> or <ostream> ought to take care of this, I believe. I'm pretty sure there's a string inserter, I'm just not sure of where it is.
Posted: Tue Sep 02, 2003 11:31 am
by just brew it!
Craig P. wrote:Either <string> or <ostream> ought to take care of this, I believe. I'm pretty sure there's a string inserter, I'm just not sure of where it is.
You are indeed correct! (It is in <string>, BTW...)
Posted: Tue Sep 02, 2003 12:45 pm
by Buub
Yes, this isn't C; time to crawl out of the cave. Use the tools that are available to you, like std::string (std::basic_string) and std::sstream and std::strstream.
Craig P. (and others) gave a good working example.
Posted: Wed Sep 03, 2003 5:10 am
by fc34
Thanks, that solved a second question of mine, which I was about to post! Cheero!