简体   繁体   English

C函数,打印到缓冲区

[英]C function, print to buffer

I have a client/ server application, and i get an error there -> perror ("[server] Can't send the message to client.\\n"). 我有一个客户端/服务器应用程序,并且在那里出现错误-> perror(“ [服务器]无法将消息发送到客户端。\\ n“)。 So the server cant' send the msgrasp ( the buffer). 因此服务器无法发送msgrasp(缓冲区)。 If you can help, I'll be grateful. 如果可以的话,我将不胜感激。

void printdir(char *dir, int depth)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;
    if((dp = opendir(dir)) == NULL) {
        fprintf(stderr,"cannot open directory: %s\n", dir);
        return;
    }
    chdir(dir);
    while((entry = readdir(dp)) != NULL) {
        lstat(entry->d_name,&statbuf);
        if(S_ISDIR(statbuf.st_mode)) {
            /* Found a directory, but ignore . and .. */
            if(strcmp(".",entry->d_name) == 0 ||
                strcmp("..",entry->d_name) == 0)
                continue;
            printf("%*s%s/\n",depth,"",entry->d_name);
            /* Recurse at a new indent level */
            printdir(entry->d_name,depth+4);
        }
        else printf("%*s%s\n",depth,"",entry->d_name);
    }
    chdir("..");
    closedir(dp);
}

int printForClient(int fd)
{
  char buffer[100];
  int bytes;
  char msg[100];
  char *msgrasp=NULL;

  bytes = read (fd, msg, sizeof (buffer));
  if (bytes < 0)
    {
      perror ("Can't read from client.\n");
      return 0;
    }
  printf ("[server]..%s\n", msg);
  printdir(&msgrasp,msj,0);    
  printf("[server]%s\n",msgrasp);

  if (bytes && write (fd, msgrasp, bytes) < 0)
    {
      perror ("[server] Can't send the message to client.\n");
      return 0;
    }

  return bytes;
}

I would suggest adding an argument of type char* (a pointer to a char array) and at every recursion advance the pointer. 我建议添加一个char *类型的参数(一个指向char数组的指针),并在每次递归时都使指针前进。 My try (supposing the buffer is long enough for the output): 我的尝试(假设缓冲区对于输出来说足够长):

void printdir(char *dir, int depth, char* output)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;
    char tmp[100];
    if((dp = opendir(dir)) == NULL) {
        fprintf(stderr,"cannot open directory: %s\n", dir);
        return;
    }
    chdir(dir);
    while((entry = readdir(dp)) != NULL) {
        lstat(entry->d_name,&statbuf);
        if(S_ISDIR(statbuf.st_mode)) {
            /* Found a directory, but ignore . and .. */
            if(strcmp(".",entry->d_name) == 0 ||
                strcmp("..",entry->d_name) == 0)
                continue;
            sprintf(tmp, "%*s%s/\n",depth,"",entry->d_name);
            strcpy(buffer, tmp);
            /* Recurse at a new indent level */
            printdir(entry->d_name,depth+4, buffer+strlen(tmp));
        }
        else printf("%*s%s\n",depth,"",entry->d_name);
    }
    chdir("..");
    closedir(dp);
}

int main()
{   char buffer[1000]; //buffer for printdir output.
    printf("Directory scan of /home:\n");
    printdir("/home",0);
    printf("done.\n");

    exit(0);
}

You might want to add \\n between every execution, depending on what you wish to do with the output. 您可能希望在每次执行之间添加\\n ,这取决于您希望对输出执行的操作。 Please note that in this program \\0 at the end of each string is deleted. 请注意,在此程序中,每个字符串末尾的\\0被删除。

This is not a very good Idea, but since it's what you requested here you have a solution with dynamic memory allocation 这不是一个很好的主意,但是由于这是您在此处所要求的,因此您有了动态内存分配的解决方案

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>

void printdir(char **output, const char *const dir, int depth)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if ((dp = opendir(dir)) == NULL)
    {
        fprintf(stderr,"cannot open directory: %s\n", dir);
        return;
    }
    chdir(dir);

    while ((entry = readdir(dp)) != NULL)
    {
        /* check if stat succeeded */
        if (lstat(entry->d_name, &statbuf) == -1)
            continue;
        if (S_ISDIR(statbuf.st_mode) != 0)
        {
            char *buffer;
            size_t length;

            /* Found a directory, but ignore . and .. */
            if(strcmp(".",entry->d_name) == 0 ||
                strcmp("..",entry->d_name) == 0)
                continue;
            length = 4 + depth + strlen(entry->d_name);
            if (*output != NULL)
                length += strlen(*output);
            buffer = realloc(*output, length);
            if (buffer != NULL)
            {
                char current[length];

                if (*output == NULL)
                    buffer[0] = '\0';
                *output = buffer;

                snprintf(current, length, "%*s%s/\n", depth, " ", entry->d_name);
                strcat(*output, current);
                //printf("%*s%s/\n",depth,"",entry->d_name);
                /* Recurse at a new indent level */
            }
            else
            {
                fprintf(stderr, "Out of memory\n");

                free(*output);
                *output = NULL;

                closedir(dp);
                return;
            }
            printdir(output, entry->d_name, depth + 4);
        }
        else
        {
            char  *buffer;
            size_t length;

            length = 4 + depth + strlen(entry->d_name);
            if (*output != NULL)
                length += strlen(*output);
            buffer = realloc(*output, length);
            if (buffer != NULL)
            {
                char current[length];

                if (*output == NULL)
                    buffer[0] = '\0';
                *output = buffer;

                snprintf(current, length, "%*s%s/\n", depth, " ", entry->d_name);
                strcat(*output, current);
            }
            else
            {
                fprintf(stderr, "Out of memory\n");

                free(*output);
                *output = NULL;

                closedir(dp);
                return;
            }
        }
    }
    chdir("..");

    closedir(dp);
}

int main()
{
    char *buffer = NULL; //buffer for printdir output.

    printf("Directory scan of /home:\n");
    printdir(&buffer, "/home", 0);
    printf("done.\n");

    printf("%s\n", buffer);
    free(buffer);

    exit(0);
}

It is not a very good Idea because you don't know if there will be enough memory to hold all the text, it could grow a lot, I added checks for that situation in this code, in the event of going out of memory, this function will abort reading, release resources and return. 这不是一个好主意,因为您不知道是否有足够的内存来容纳所有文本,它可能会增长很多,我在这段代码中针对这种情况添加了检查,以防出现内存不足的情况,此函数将中止读取,释放资源并返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM