Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. [C]Strings' array goes crazy.

[C]Strings' array goes crazy.

Scheduled Pinned Locked Moved C / C++ / MFC
data-structures
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    militandri
    wrote on last edited by
    #1

    Hi everyone. I wrote a function that should copy in a strings' array all the name of several files contained in a folder.

    void get_filenames(char dir[]){
    int i=0;
    DIR *sd;

    sd = opendir(dir);
    struct dirent \*dird;
    
    printf("\\nLa cartella %s contiene %d files.", dir, n\_files);    //"Folder %s contains %d files."
    	
    seekdir(sd, 2);
    
    for(i=0;id\_name;
    	printf("\\n%s", filenames\[i\]);
    }
    
    closedir(sd);
    

    }

    When I call this function it seems to be alright, and the printf contained in the for cicle prints the names of files correctly... But if I try to print these names somewhere out of this function, I see that each string of filenames[] contains the last string printed in the get_filenames function, that is the last file in the folder. I allocated filenames[] in another void function, this way:

    ...
    filenames = malloc(n_files * sizeof(char));
    for(i=0;i

    F enhzflepE 2 Replies Last reply
    0
    • M militandri

      Hi everyone. I wrote a function that should copy in a strings' array all the name of several files contained in a folder.

      void get_filenames(char dir[]){
      int i=0;
      DIR *sd;

      sd = opendir(dir);
      struct dirent \*dird;
      
      printf("\\nLa cartella %s contiene %d files.", dir, n\_files);    //"Folder %s contains %d files."
      	
      seekdir(sd, 2);
      
      for(i=0;id\_name;
      	printf("\\n%s", filenames\[i\]);
      }
      
      closedir(sd);
      

      }

      When I call this function it seems to be alright, and the printf contained in the for cicle prints the names of files correctly... But if I try to print these names somewhere out of this function, I see that each string of filenames[] contains the last string printed in the get_filenames function, that is the last file in the folder. I allocated filenames[] in another void function, this way:

      ...
      filenames = malloc(n_files * sizeof(char));
      for(i=0;i

      F Offline
      F Offline
      Freak30
      wrote on last edited by
      #2

      The line filenames = malloc(n_files * sizeof(char)); should be filenames = malloc(n_files * sizeof(char *)); because you use it to allocate pointers. You don't show the declaration of filenames in the sample, but I assume it's char **. By the way, what happens if a file in the directory has a name longer than 19 characters?

      The good thing about pessimism is, that you are always either right or pleasently surprised.

      1 Reply Last reply
      0
      • M militandri

        Hi everyone. I wrote a function that should copy in a strings' array all the name of several files contained in a folder.

        void get_filenames(char dir[]){
        int i=0;
        DIR *sd;

        sd = opendir(dir);
        struct dirent \*dird;
        
        printf("\\nLa cartella %s contiene %d files.", dir, n\_files);    //"Folder %s contains %d files."
        	
        seekdir(sd, 2);
        
        for(i=0;id\_name;
        	printf("\\n%s", filenames\[i\]);
        }
        
        closedir(sd);
        

        }

        When I call this function it seems to be alright, and the printf contained in the for cicle prints the names of files correctly... But if I try to print these names somewhere out of this function, I see that each string of filenames[] contains the last string printed in the get_filenames function, that is the last file in the folder. I allocated filenames[] in another void function, this way:

        ...
        filenames = malloc(n_files * sizeof(char));
        for(i=0;i

        enhzflepE Offline
        enhzflepE Offline
        enhzflep
        wrote on last edited by
        #3

        I think you'll find that the line:

        filenames[i]=dird->d_name;

        should actually be something like:

        filenames[i]=strdup(dird->d_name);

        You see, dird->d_name is a location in memory that the current file's name is copied to - _but_ this location doesn't change, only the contents of the text does. What your code does is set each of the filename[] elements to hold this location. In the next iteration of the loop, the text contained there changes, but the location doesn't. So you've got all elements of filename[] holding the same address of a string. If, on the other-hand, you make a duplicate of the string in dird->d_name and then store _that_ location into filenames[], each element of filenames[] will point to a different location in memory - locations that contain the string you're after. Note - you should also change your last code-block.

        filenames = malloc(n_files * sizeof(char*) );

        So, 1) filenames should be a char** (I expect you've got it setup to be a char* currently) 2) each element (a char*) should contain the address of the duplicated string 3) No need for the filenames[i] = malloc(20 * sizeof(char) ); code.

        M 1 Reply Last reply
        0
        • enhzflepE enhzflep

          I think you'll find that the line:

          filenames[i]=dird->d_name;

          should actually be something like:

          filenames[i]=strdup(dird->d_name);

          You see, dird->d_name is a location in memory that the current file's name is copied to - _but_ this location doesn't change, only the contents of the text does. What your code does is set each of the filename[] elements to hold this location. In the next iteration of the loop, the text contained there changes, but the location doesn't. So you've got all elements of filename[] holding the same address of a string. If, on the other-hand, you make a duplicate of the string in dird->d_name and then store _that_ location into filenames[], each element of filenames[] will point to a different location in memory - locations that contain the string you're after. Note - you should also change your last code-block.

          filenames = malloc(n_files * sizeof(char*) );

          So, 1) filenames should be a char** (I expect you've got it setup to be a char* currently) 2) each element (a char*) should contain the address of the duplicated string 3) No need for the filenames[i] = malloc(20 * sizeof(char) ); code.

          M Offline
          M Offline
          militandri
          wrote on last edited by
          #4

          Thank you for the answer. Of course I declared filenames as char**... :cool: But I didn't know really good how the d_name variable works, then I made some mistakes... Now it's all clearer!

          enhzflepE 1 Reply Last reply
          0
          • M militandri

            Thank you for the answer. Of course I declared filenames as char**... :cool: But I didn't know really good how the d_name variable works, then I made some mistakes... Now it's all clearer!

            enhzflepE Offline
            enhzflepE Offline
            enhzflep
            wrote on last edited by
            #5

            You're welcome. I'd hoped you had, though the way you used it gave me the impression it was only a char* Glad to be of help. :)

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups