C: How could I send a list of file names as a string on a socket?

问题内容:

I’m trying to take file names from a dirent struct, and send a list of all names as a concatenated string to the client.

After a few hours of trying to figure it out, I can’t seem to allocate memory properly, or read it properly, I’m getting nonsense string back, so It must be reading memory wrong, even though I think I’ve appended the string with “\0”

Here is what I’ve done so far,

Send string to client:

void send_file_list(int socketNumber)
{

    DIR *mydir;
    if ((mydir = opendir("upload")) == NULL) {
    perror("error");
    exit(EXIT_FAILURE);
    }

    struct dirent *entry = NULL;

    size_t len;

    //loop through entry to get size of all filenames as string.
    while ((entry = readdir(mydir)) != NULL)
    {
    len = len + strlen(entry->d_name);
    }

    char filelist[len];

    //returns NULL when dir contents all processed
    while ((entry = readdir(mydir)) != NULL)
    {
    strcat(strcat(filelist, entry->d_name),"\n");
    }

    closedir(mydir);

    size_t n = len;

    writen(socketNumber, (unsigned char *) &n, sizeof(size_t)); 
    writen(socketNumber, (unsigned char *) filelist, n);

    printf("Sent file list of size %zu bytes\n",n);

}//end send_file_list()

Get string from server:

void get_file_list(int socket)
{
    size_t k;

    readn(socket, (unsigned char *) &k, sizeof(size_t));
    char filelist[k];   
    readn(socket, (unsigned char *) filelist, k);

    printf("Received: %zu bytes\n\n", k);
    printf("\n---Files On Server -------------------\n");
    printf("%s", filelist);
    printf("\n--------------------------------------\n"); 

} // end get_file_list()

I’ve been at it for hours, and I feel It’s getting messy. Is there a better way of doing this?

问题评论:

1  
Have you any compile time warning? BTW, you cat one char more that you reserver because of the \n used to separate the file names, which leads to undefined behaviour.
    
@Serge Ballesta No complie time warnings
– Gavin Macleod
9 hours ago
2  
You use readdir() to read thru the list of files to get the length, then you try to readdir() again to process the list… you must close the directory-stream, with closedir(), and opendir() it again before re-using it. Second, in your calculation of the “length”, you are not allowing for a “separator”, such as a comma or a newline…
1  
Try to print “filelist” in the second loop everytime before you append the new filename from directory to it to see what value is has. Also, pay attention to @SergeBallesta comment. You are infact appending one extra character for each filename more than what you have allocated and you have also not taken into account the last ‘\0’ character.
    
The question was about char filelist[len];. That defines a Variable Length Array which is an optional feature, and some compilers (MSVC) do not support it and just offer a 0 size array. You should try size_t len = 0; to initialize the variable (an uninitialized automatic variable receives an unspecified value) and len = len + strlen(entry->d_name) + 1; to reserve some space for the \n.

答案:

答案1:

this loop:

while ((entry = readdir(mydir)) != NULL)
{
len = len + strlen(entry->d_name);
}

has a couple of problems.

1) Generic to the whole posted code, the indenting is not consistent. For consistency, indent after every opening brace ‘{‘. unindent before every closing brace ‘}’. Suggest each indent level be 4 spaces.

2) There are lots of kinds of entries in the directory entries. (links, sub directories, etc etc)

Before including any specific ‘file name’ in the resulting string. the code needs to check the type of entry to assure it is a normal file AND the name of the file is NOT . nor ..

====
the variable: len is not initialized, suggest using:

size_t len = 0;

====
Note that the function strlen() returns the offset to the NUL byte at the end of the string (and offsets start at 0, not 1) so the actual length is 1 byte longer

====
The question doesn’t state: is this code to collect only the current directory file names or is it to include the file names in the sub directories?

====
The question doesn’t state: are the file names to be jammed together or separated by a space or comma. If separated by a space, what about file names that contain a space?

====
BTW: where do the function names: writen() and readn() come from?

答案评论:

原文地址:

https://stackoverflow.com/questions/47747765/c-how-could-i-send-a-list-of-file-names-as-a-string-on-a-socket

Tags:, ,

Add a Comment