Simple C string management

I am trying to do some very string processing of strings in C (for example, with a file name, chop off the file extension, manipulate the file name, and then add it back to the extension). I'm pretty rusty in C and getting segmentation errors.

char* fname;
char* fname_base;
char* outdir;
char* new_fname;
.....
fname = argv[1];
outdir = argv[2];
fname_len = strlen(fname);
strncpy(fname_base, fname, (fname_len-4)); // weird characters at the end of the truncation?
strcpy(new_fname, outdir); // getting a segmentation on this I think

strcat(new_fname, "/");
strcat(new_fname, fname_base);
strcat(new_fname, "_test");
strcat(new_fname, ".jpg");
printf("string=%s",new_fname);  

Any suggestions or pointers are welcome.

Many thanks and apologies for such a basic question

+3
source share
8 answers

You need to allocate memory for new_fnameand fname_base. Here's how you do it for new_fname:

new_fname = (char*)malloc((strlen(outdir)+1)*sizeof(char));

In strlen(outdir)+1part 1 it intended to allocate memory for the terminator NULL CHARACTER '\0' .

+3
source

, ,

strncpy(fname_base, fname, (fname_len-4));

, 4 (.???). 3 , , . , ( , "." ). , "C" (!)

char *s;
s = (char *) strrchr (fname, '.');
if (s == 0)
{
    strcpy (fname_base, fname);
}
else
{
    strncpy (fname_base, fname, strlen(fname)-strlen(s));
    fname_base[strlen(fname)-strlen(s)] = 0;
}
+2

malloc fname_base new_fname, .

fname_base = (char *)(malloc(sizeof(char)*(fname_len+1)));
fname_base[fname_len] = 0; //to stick in the null termination

new_fname outdir

+1

strcpy: fname_base new_fname: char, .

char fname_base[FILENAME_MAX];
char new_fname[FILENAME_MAX]; 
+1

malloc, ,

if ( asprintf(&new_fname,"%s/%s_text.jpg",outdir,fname_base) >= 0 )
     // success, else failed

- free(new_fname), .

( , GNU, * BSD)

+1

:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

const char *extra = "_test.jpg";

int main(int argc, char** argv)
{
  char *fname = strdup(argv[1]); /* duplicate, we need to truncate the dot */
  char *outdir = argv[1];
  char *dotpos;
  /* ... */
  int new_size = strlen(fname)+strlen(extra);
  char *new_fname = malloc(new_size);   
  dotpos = strchr(fname, '.');
  if(dotpos)
    *dotpos = '\0'; /* truncate at the dot */
  new_fname = malloc(new_size);
  snprintf(new_fname, new_size, "%s%s", fname, extra);
  printf("%s\n", new_fname);
  return 0;
}
+1

malloc.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

/*  Change this to '\\' if you are doing this on MS-windows or something like it. */
#define DIR_SYM '/'
#define EXT_SYM '.'
#define NEW_EXT "jpg"


int main(int argc, char * argv[] ) {
   char * fname;
   char * outdir;

   if (argc < 3) {
       fprintf(stderr, "I want more command line arguments\n");
       return 1;
   }
   fname = argv[1];
   outdir = argv[2];

   char * fname_base_begin = strrchr(fname, DIR_SYM); /* last occurrence of DIR_SYM */
   if (!fname_base_begin) {
       fname_base_begin = fname; // No directory symbol means that there nothing
                                 // to chop off of the front.
   }

   char * fname_base_end = strrchr(fname_base_begin, EXT_SYM);
   /* NOTE: No need to search for EXT_SYM in part of the fname that we have cut off
    * the front and then have to deal with finding the last EXT_SYM before the last
    * DIR_SYM */
   if (!fname_base_end) {
       fprintf(stderr, "I don't know what you want to do when there is no extension\n");
       return 1;
   }

   *fname_base_end = '\0'; /* Makes this an end of string instead of EXT_SYM */
   /* NOTE:  In this code I actually changed the string passed in with the previous
    * line.  This is often not what you want to do, but in this case it should be ok.
    */

   // This line should get you the results I think you were trying for in your example
   printf("string=%s%c%s_test%c%s\n", outdir, DIR_SYM, fname_base_begin, EXT_SYM, NEW_EXT);

   // This line should just append _test before the extension, but leave the extension
   // as it was before.
   printf("string=%s%c%s_test%c%s\n", outdir, DIR_SYM, fname_base_begin, EXT_SYM, fname_base_end+1);

   return 0;
} 

, , , printf , fname.

, , , sprintf .

, fname, :

printf("string=%s%c%*s_test%c%s\n", outdir, DIR_SYM, (unsigned)fname_base_begin -(unsigned)fname_base_end, fname_base_begin, EXT_SYM, fname_base_end+1);

printf, .

+1

C , ( , ......) , "". - (type *x) , , , , , malloc ( ) , char buf[size].

.

, sprintf ( ) . , strcat, , strcat "" , (ops!) , "" : , , , , strcat .

strcat char, strlen . ,

size_t l = strlen(new_fname);
new_fname[l++] = '/';
for(i = 0; fname_base[i] != 0; i++, l++) new_fname[l] = fname_base[i];
for(i = 0; testjpgstring[i] != 0; i++, l++) new_fname[l] = testjpgstring[i];
new_fname[l] = 0; // terminate the string...

l... (testjpgstring = "_test.jpg" )

However, if your program is full of string manipulations, I suggest using a library for strings (for laziness I often use glib)

0
source

Source: https://habr.com/ru/post/1758526/


All Articles