Reputation: 34513
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.
Upvotes: 9
Views: 14898
Reputation: 33
A cleaner but slower implementation might be to fully fill all remaining characters with null characters using memset:
#include <stdio.h>
#include <string.h>
int main() {
char myString[100] = "This is a long string.";
myString[8] = '\0';
// Fill the remaining elements after the null terminator with '\0'
memset(&myString[9], '\0', sizeof(myString) - 9);
printf("Truncated string: %s\n", myString); // Output: "This is "
return 0;
}
Might lead to less confusion when using gdb
, as gdb
might also show the characters after the null character.
It is also less prone to bugs when you accidentally try to access elements of the array after the null character.
But I guess just placing the null character at the position where you want to truncate will be fine in most situations.
Upvotes: 0
Reputation: 3990
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 );
}
Upvotes: 1
Reputation: 1198
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);
}
Upvotes: 1
Reputation: 36082
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';
Upvotes: 2
Reputation: 490028
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);
Upvotes: 2
Reputation: 1019
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
Upvotes: 2
Reputation: 17016
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
).
Upvotes: 18