Thread: Combining strings

  1. #1
    Astrophysics student Ayreon's Avatar
    Join Date
    Mar 2009
    Location
    Netherlands
    Posts
    79

    Combining strings

    I've been searching this forum for my problem, but couldn't find any related topics, maybe I overlooked them. Anyway, I would like to combine 2 strings into 1.

    I've got an array full of filenames without the txt extention. I need the names without extention as well, so what I wanted to do is something like this:

    Code:
    char* filename_array[84] = "filename1","filename2", etc...
    
    char* filename1 = filename_array[0]".txt"; 
    
    FILE* file = fopen(filename1,"r");
    So how can I make that second line work?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    A temporary string and strcpy() + strcat() or sprintf().

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Astrophysics student Ayreon's Avatar
    Join Date
    Mar 2009
    Location
    Netherlands
    Posts
    79
    I don't know how these functions work, so I looked them up through google.
    I'm not sure why I can't just use strcat.
    It seems to stick the string from the second argument to the first argument.
    I tried this:

    Code:
    char* bla = "bla";
    char* txt = ".txt";
    char* filename;
    
    filename = (char*) malloc (200); //maybe I need to allocate some mem for my new string?
    
    filename = strcat(bla,txt);
    
    printf("%s",filename);
    Obviously it doesn't work, but I don't know why.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You do not have to malloc the memory, unless you need it outside of the function you are in at the moment. You only need malloc if you need the filename to stay around when leaving the current function. Otherwise, just use a local char array that is big enough (PATH_MAX is a good candidate for "big enough").

    And you need to strcpy() the first part to your filename variable, then strcat the second half onto filename.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Feb 2009
    Posts
    138
    strcat modifies the first argument and a pointer to a string constant can't be modified. try this instead.
    Code:
    strcpy(filename, bla);
    strcat(filename, txt);

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    This is a memory leak:
    Code:
    filename = (char*) malloc (200); 
    filename = strcat(bla,txt);
    Because you move the pointer. The first line points it to a block of memory, then you move it to point to something else, meaning you now have nothing pointing to that block you assigned (so that protected chunk of memory is useless).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Note that
    Code:
    char* bla = "bla";
    char* txt = ".txt";
    should really be const char, since you can not modify the strings here.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Astrophysics student Ayreon's Avatar
    Join Date
    Mar 2009
    Location
    Netherlands
    Posts
    79
    It works now, I used Meldreths box.

    Isn't there a nicer way to do this, what if wanted to combine several strings into one, wouldn't that get a little messy?

    edit: to matsp:
    Tanks for the heads up. Does it make a difference bytheway?

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Look
    Code:
    char filenames[10][256]={"this", "that","etc"},
             tmp[256];
    If you want to use "this.txt" without changing filenames[0] permanently to "this.txt":
    Code:
    sprintf(tmp, "%s.txt", filenames[0]);
    If you don't mind changing filenames[0] permanently, you could do the same thing to it.

    Read up on sprintf, it's great. If you have a long enough array:
    Code:
    sprintf(tmp, "copy %s.txt to %s.txt", filenames[0], filenames[1]);
    Make sure you understand what I said before about leaks too.
    Last edited by MK27; 03-03-2009 at 09:50 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Ayreon View Post
    It works now, I used Meldreths box.

    Isn't there a nicer way to do this, what if wanted to combine several strings into one, wouldn't that get a little messy?

    edit: to matsp:
    Tanks for the heads up. Does it make a difference bytheway?
    Like I said, there's sprintf that can do many combinations in one line of code, e.g.
    Code:
    sprintf(filename, "%s%03d%s", bla, number, txt);
    will make "bla001.txt" - obviously, filename needs to be a valid array or malloc'd memory.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    Astrophysics student Ayreon's Avatar
    Join Date
    Mar 2009
    Location
    Netherlands
    Posts
    79
    I like that function. But like strcpy and strcat, it works fine on its own, but now that I'm using it in my actual program, it crashes. Clearly I'm doing something else wrong.

    This is the function I'm calling in my program (That's as good as the whole program):

    Code:
    long Linecount(char* filename_array[],int n){
    
         char* filename; 
    
         sprintf(filename, "%s.txt", filename_array[0]);
    
         printf("%s",filename);
    
         FILE* file = fopen(filename,"r");
         
         
    //     if (file!=NULL){
    //     
    //     dummyline = (char*) malloc (100);
    //     
    //     
    //     
    //     
    //     while ( fgets(dummyline, 100, file) != NULL) aantal_regels++;     
    //
    //     return aantal_regels;
    //          
    //     free (dummyline);  
    //     
    //     fclose(file); 
    //     
    //     } 
          
    
    }
    Maybe one of those memory leaks?

  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    filename is not pointing anywhere, try making it an array instead.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    Astrophysics student Ayreon's Avatar
    Join Date
    Mar 2009
    Location
    Netherlands
    Posts
    79
    Ah, that works, but how big should i make it, I'm never very fond of these numbers. Now I used this:
    char filename[100];

    Is that big, small, just right?

  14. #14
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Ayreon View Post
    Maybe one of those memory leaks?
    The opposite -- now you're not using too much memory (that will not be fatal or cause an error, which is why it's important to recognize, or you will just do it all the time by accident without caring).

    Anyway
    Code:
         char* filename; 
    
         sprintf(filename, "%s.txt", filename_array[0]);
    filename is a pointer to no memory at all! There is a difference between using the return value of a function like strcpy, in which case the pointer is reassigned (moved; so there is no point in you assigning any memory first), and passing a pointer in as an argument, in which case it is not moved or reassigned -- but the memory it (hopefully) points to will get used. So either
    Code:
    char *filename=malloc(256);
    or
    char filename[256];
    In this case the second one is better, since you are just using the variable inside the function.

    If there is not enough memory assigned to the pointer, sprintf (or strcat, w/r/t the 1st parameter) will very likely overwrite something else that could be important, causing a crash.

    100 is probably long enough if you know how long filename is.

    You could just use PATH_MAX (an already included variable used to limit the length of a complete filename with path) because it is usually obscenely large enough.
    Last edited by MK27; 03-03-2009 at 10:18 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #15
    Astrophysics student Ayreon's Avatar
    Join Date
    Mar 2009
    Location
    Netherlands
    Posts
    79
    Is it alright if I post further questions on this program here? It doesn't have anything to do with strings anymore.

    I'm counting starsystems in tekstfiles and every system consists of 3 lines. I've made this function for counting the lines in the file. For the number of systems I simply use no_systems=lines/3.
    But what if there is an extra empty line at the bottom of the file? Then no_sytems won't be an integer anymore and I can't rely on the outcome anymore.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strings Program
    By limergal in forum C++ Programming
    Replies: 4
    Last Post: 12-02-2006, 03:24 PM
  2. Programming using strings
    By jlu0418 in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2006, 08:07 PM
  3. Reading strings input by the user...
    By Cmuppet in forum C Programming
    Replies: 13
    Last Post: 07-21-2004, 06:37 AM
  4. combining multiple strings into 1 string
    By Leeman_s in forum C++ Programming
    Replies: 3
    Last Post: 01-27-2003, 09:49 PM
  5. menus and strings
    By garycastillo in forum C Programming
    Replies: 3
    Last Post: 04-29-2002, 11:23 AM