Personal computing discussed

Moderators: renee, SecretSquirrel, just brew it!

 
fc34
Minister of Gerbil Affairs
Topic Author
Posts: 2816
Joined: Wed May 08, 2002 8:39 am
Location: Somewhere

Substring in C++

Mon Sep 01, 2003 8:59 am

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!
Windows XP - The 64-bit wannabe with a 32-bit graphics interface for 16-bit extensions to a 8-bit patch on a 4-bit operating system designed to run on a 2-bit processor by a company that can't stand 1-bit of competition
 
sativa
Grand Gerbil Poohbah
Posts: 3044
Joined: Sun Apr 14, 2002 7:22 pm
Location: lafayette, la

Mon Sep 01, 2003 10:07 am

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 ?
 
sativa
Grand Gerbil Poohbah
Posts: 3044
Joined: Sun Apr 14, 2002 7:22 pm
Location: lafayette, la

Mon Sep 01, 2003 10:39 am

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
 
Craig P.
Gerbil Team Leader
Posts: 285
Joined: Tue Dec 31, 2002 3:12 am
Location: South Bend, IN

Mon Sep 01, 2003 10:58 am

#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)
 
fc34
Minister of Gerbil Affairs
Topic Author
Posts: 2816
Joined: Wed May 08, 2002 8:39 am
Location: Somewhere

Tue Sep 02, 2003 12:33 am

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
Windows XP - The 64-bit wannabe with a 32-bit graphics interface for 16-bit extensions to a 8-bit patch on a 4-bit operating system designed to run on a 2-bit processor by a company that can't stand 1-bit of competition
 
fc34
Minister of Gerbil Affairs
Topic Author
Posts: 2816
Joined: Wed May 08, 2002 8:39 am
Location: Somewhere

Tue Sep 02, 2003 5:23 am

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?
Windows XP - The 64-bit wannabe with a 32-bit graphics interface for 16-bit extensions to a 8-bit patch on a 4-bit operating system designed to run on a 2-bit processor by a company that can't stand 1-bit of competition
 
Yahoolian
Grand Gerbil Poohbah
Posts: 3577
Joined: Sun Feb 16, 2003 3:43 pm
Location: MD
Contact:

Tue Sep 02, 2003 5:59 am

Do you want to replace fname with argv or just add argv to the end of the string fname?
 
fc34
Minister of Gerbil Affairs
Topic Author
Posts: 2816
Joined: Wed May 08, 2002 8:39 am
Location: Somewhere

Tue Sep 02, 2003 6:53 am

basically, i want

fname = argv[1]

but this returns a 'cannot assign char * to string'
Windows XP - The 64-bit wannabe with a 32-bit graphics interface for 16-bit extensions to a 8-bit patch on a 4-bit operating system designed to run on a 2-bit processor by a company that can't stand 1-bit of competition
 
liquidsquid
Minister of Gerbil Affairs
Posts: 2661
Joined: Wed May 29, 2002 10:49 am
Location: New York
Contact:

Tue Sep 02, 2003 7:52 am

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.
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Tue Sep 02, 2003 7:56 am

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;
}
Nostalgia isn't what it used to be.
 
Craig P.
Gerbil Team Leader
Posts: 285
Joined: Tue Dec 31, 2002 3:12 am
Location: South Bend, IN

Tue Sep 02, 2003 8:59 am

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.
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Tue Sep 02, 2003 9:17 am

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)
Nostalgia isn't what it used to be.
 
fc34
Minister of Gerbil Affairs
Topic Author
Posts: 2816
Joined: Wed May 08, 2002 8:39 am
Location: Somewhere

Tue Sep 02, 2003 9:29 am

Thank you!

My program works now :)
Windows XP - The 64-bit wannabe with a 32-bit graphics interface for 16-bit extensions to a 8-bit patch on a 4-bit operating system designed to run on a 2-bit processor by a company that can't stand 1-bit of competition
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Tue Sep 02, 2003 9:34 am

What was causing the 'cannot assign char * to string' error? (Just curious...)
Nostalgia isn't what it used to be.
 
Craig P.
Gerbil Team Leader
Posts: 285
Joined: Tue Dec 31, 2002 3:12 am
Location: South Bend, IN

Tue Sep 02, 2003 11:16 am

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.
 
just brew it!
Administrator
Posts: 54500
Joined: Tue Aug 20, 2002 10:51 pm
Location: Somewhere, having a beer

Tue Sep 02, 2003 11:31 am

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...)
Nostalgia isn't what it used to be.
 
Buub
Maximum Gerbil
Posts: 4969
Joined: Sat Nov 09, 2002 11:59 pm
Location: Seattle, WA
Contact:

Tue Sep 02, 2003 12:45 pm

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.
 
fc34
Minister of Gerbil Affairs
Topic Author
Posts: 2816
Joined: Wed May 08, 2002 8:39 am
Location: Somewhere

Wed Sep 03, 2003 5:10 am

Thanks, that solved a second question of mine, which I was about to post! Cheero!
Windows XP - The 64-bit wannabe with a 32-bit graphics interface for 16-bit extensions to a 8-bit patch on a 4-bit operating system designed to run on a 2-bit processor by a company that can't stand 1-bit of competition

Who is online

Users browsing this forum: No registered users and 1 guest
GZIP: On