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

char fname = "test.txt"


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)" :o)

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)" :o)

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!