A char*
pointer actually just points to a single char
object. If that object happens to be the first (or any) element of a string, you can use pointer arithmetic to access the other elements of that string -- which is how strings (C-style strings, not C++-style std::string
objects) are generally accessed.
A (C-style) string is simply a sequence of characters terminated by a null character ('\0
'). (Anything after the '\0'
terminator isn't part of the string.) So a string "foo bar"
consists of this sequence of characters:
{ 'f', 'o', 'o', ' ', 'b', 'a', 'r', '\0' }
If you want to change the string from "foo bar"
to just "foo"
, one way to do it is simply to replace the space character with a null character:
{ 'f', 'o', 'o', '\0', ... }
The ...
is not part of the syntax; it represents characters that are still there ('b'
, 'a'
, 'r'
, '\0'
), but are no longer part of the string.
Since you're using C++, you'd probably be much better off using std::string
; it's much more powerful and flexible, and frees you from having to worry about terminators, memory allocation, and other details. (Unless the point of this exercise is to learn how C-style strings work, of course.)
Note that this modifies the string pointed to by file
, and that change will be visible to the caller. You can avoid that by making a local copy of the string (which requires allocating space for it, and later freeing that space). Again, std::string
makes this kind of thing much easier.
Finally, this:
strncpy(file, file, j);
is bad on several levels. Calling strncpy()
with an overlapping source and destination like this has undefined behavior; literally anything can happen. And strncpy()
doesn't necessarily provide a proper NUL terminator in the destination. In a sense, strncpy()
isn't really a string function. You're probably better off pretending it doesn't exist.
See my rant on the topic.