tags:

views:

130

answers:

6
char out_file_name[30];  


ogSize = strlen(FileName); //i.e. - FileName_anylength.log (always.log)
ogSize -= strlen(IN_FILE_SUFFIX); //amount of chars before .log

strncpy( out_file_name, FileName, ogSize ); //out_file_name now is FileName_anylength (without the .log)  

Is this the best way to do this?

Also, how do I guard that ogSize doesn't happen to be more than 30 chars as it is coming from user input?

Thank You.

+12  A: 

With a C-style string, you can just set the character you want to truncate on to \0.

Regarding your second question, basically you check. Or you allocate as much memory as you need, based on the string size (remember to include room for that \0).

jkerian
+1 Good trick. Strlen will stop on the first instance of `\0`
0A0D
@jkerian: Nice solution, thanks.
Tommy
+2  A: 

Give this a look:

char *trunc;
char *outfile;

strdup( outfile, FileName );

if ( ((trunc = strstr( out_file_name, ".log" )) != NULL )
 *trunc = '\0';

return ( outfile );  // assumes returning result from function
BillP3rd
strdup is not ANSI C (no C89,no C99)
It is sufficiently well known and standard to be safely used in most environments: IEEE 1003.1, 2004, (http://www.opengroup.org/onlinepubs/009695399/functions/strdup.html); SVr4, 4.3BSD, POSIX.1-2001 (http://linux.die.net/man/3/strdup), and Unix 98 (http://www.mkssoftware.com/docs/man3/strdup.3.asp). Also, my solution makes no assumptions about the length of the source string and it preserves it.
BillP3rd
+2  A: 

Taking your last question first, ensuring a maximum size is pretty easy. Typically you want to use fgets to read the string. This allows you to specify a maximum length. Alternatively, you can specify a maximum size in a scanf format (e.g., "%29s" or "%29[^\n]"). Note the difference between the two: with fgets you specify the buffer size, but with scanf you specify one less than the buffer size (i.e., the maximum number of characters to read).

As for the first question: yes, there are generally better ways. strncpy is a strange function, originally written for a fairly specific purpose, and (to be honest) should probably be removed from the standard library, because while it seems like it should be useful, it almost never really is.

I'd probably do things a little differently. One possibility would be to use snprintf, something like:

snprintf(
    out_file_name,
    sizeof(out_file_name),
    "%*s",
    strlen(FileName) - strlen(IN_FILE_SUFFIX), FileName);
Jerry Coffin
if out_file_name is not an array, your example works not.snprintf is not C89
+2  A: 

use fgets() to read the string from the user, that way you can specify a max length of the string

char* from = FileName;
char* to   = out_file_name;
int curLen = 0;

do
{
  *to++=*from++
}
while(*from && *from!='.' && ++curLen < ogSize);

*to='\0';
Anders K.
works not for more than one '.' in from
+1  A: 

You can insert a null into the string to shorten it. Below the function strstr() is used to find the address of the first occurrence of ".log". After that you can subtract the two addresses from each other to find out the length of the name and where to insert the null.

int main() { 
    char suffix[] = ".log";  
    char filename[] = "FileName_anylength.log";  
    char* end_address = strstr(filename, suffix);  
    filename[end_address-filename] = 0;  
    printf("%s", filename);  
}
skimobear
@BillP3rd - Apologies Bill, just noticed we had similar answers. I like yours better, no subtraction. - cheers :)
skimobear
+1  A: 
char out_file_name[30];
char *suffix=".log";
size_t IN_FILE_SUFFIX = strlen(suffix);

/* also works, if suffix occurs more than 1 time or never ! */
if( strstr( out_file_name, suffix ) )
  out_file_name[ strlen(out_file_name) - IN_FILE_SUFFIX ] = 0;

or

char out_file_name[30];
char *suffix=".log";
size_t IN_FILE_SUFFIX = strlen(suffix);

/* also works, if suffix occurs more than 1 time or never ! */
if( strstr( out_file_name, suffix ) )
{
  char format[20];
  sprintf( format, "%%.%ds", strlen(out_file_name) - IN_FILE_SUFFIX );
  sprintf( out_file_name, format, out_file_name );
}