【问题标题】:Creating dynamically a file name in C在 C 中动态创建文件名
【发布时间】:2020-04-08 07:11:05
【问题描述】:

我正在开发一个客户端、服务器项目。我收到来自服务器的响应,我必须在其中创建两个文件。第一个文件是 .html 文件,第二个文件是 .png 文件。我解析响应并尝试在while 循环中动态创建文件。

...
FILE *fwrp;
char *response = malloc(MAXDATASIZE * sizeof(char));
memset(response, '\0', sizeof(char) * MAXDATASIZE);
char *r = &response[0];


while (fread(field, sizeof(field), 1, fpr)) {
    for (int i = 0; i < MAXDATASIZE; i++) {
        *r = field[i];
        r++;


//Some unecessary code...

                    if (strstr(response,"file=")){
                    char* newFileName = strchr(response, '=');
                    newFileName++;
                    fwrp = fopen(newFileName, "w");
                    data = false;
//...  

我希望我没有删减太多必要的信息。 问题如下:文件已创建。还有正确的内容。 问题只是文件的动态名称。有一次名称应该是ok.png,但实际上它是'ok.png'$'\n' html文件的同样问题。名称应为example.html,但为'example.html'$'\n'

已尝试在创建名称之前打印它们。它们在打印时具有正确的格式。我尝试使用strdup 分配内存,但由于某种原因它不起作用。有人知道为什么会出现这个问题吗?

解决方案:

对于那些有兴趣的人。这是我的解决方案

int receiveResponse(int sockfd) {
int sdw = dup(sockfd);
FILE *fpr = fdopen(sdw, "r");
FILE *fwrp;
int lenOfRecord = 0;
bool data = false;
bool status_checked = false;
bool first = true;
unsigned char field[MAXDATASIZE] = {0};
char *response = malloc(MAXDATASIZE * sizeof(char));
memset(response, '\0', sizeof(char) * MAXDATASIZE);
char *r = &response[0];




while (fread(field, sizeof(field), 1, fpr)) {
    for (int i = 0; i < MAXDATASIZE; i++) {

        *r = field[i];
        r++;



        if ((field[i] == '\n') && (data == false)){

            if (strstr(response, "status=") && (status_checked == false)){
                status_checked = true;
                char* status = strchr(response,'=');
                status++;
            }

            if (strstr(response, "len=")){
                char *len = strchr(response, '=');
                len++;
                char *ptr;
                lenOfRecord = strtol(len,&ptr,10);
                data = true;
                first = true;
            }

            if (strstr(response,"file=")){
                char* tmp = strchr(response, '=');
                tmp++;
                char* newFileName = malloc(strlen(tmp) * sizeof(char));
                memcpy(newFileName, tmp, strlen(tmp)  * sizeof(char));
                newFileName[strlen(newFileName) - 1] = 0;
                fwrp = fopen(newFileName, "w");

                free(newFileName);
                data = false;
            }


            free(response);
            char* response = malloc(MAXDATASIZE * sizeof(char));
            memset(response, '\0', sizeof(char) * MAXDATASIZE);
            r = &response[0];
        }


        if (--lenOfRecord == 0){
            data = false;
            fflush(fwrp);
            fclose(fwrp);

        }

        if ((data == true) && (first == false)) {
            fputc(field[i], fwrp);
        }

        if ((data == true) && (first == true)){
            first = false;
        }



    }


}



}

所以这个修改解决了问题

 newFileName[strlen(newFileName) - 1] = 0;

【问题讨论】:

  • “响应”从何而来?显然,您希望它看起来像“file=name”,而实际上它看起来像“file='name'...”。如果是后者,则必须自己解析。
  • 感谢您的回答。响应看起来像这样 file=example.html
  • 我也编辑了我的问题。这样您就可以看到响应来自哪里
  • 您能否在调用 fopen 之前对 ok.pngnewFileName 指针的内容进行字符串比较。你在windows+VS、linux+gcc是什么平台?
  • 可以在调用 fopen() 之前打印 newFileName 吗?如果最后有不需要的字符,在调用 fopen() 之前在那里重新处理,可以解决问题,但它不能解释为什么会出现问题。

标签: c string file server client


【解决方案1】:
  1. 我不知道,你为什么要将阅读的 field 内容复制到 response 而不是严格阅读到 response。另外,您没有显示field 的声明。

  2. 也许您应该更加注意读取字符的计数(由fread() 返回):它可以是负数(意味着:错误),而不仅仅是正数或 0。

  3. 零终止呢?

所以,我的提议是:

//...
// for better readability
#define MAX_RESPONSE_SIZE (MAXDATASIZE * sizeof(char))

// below: added 1 byte for preserving the proper string termination ('\0' byte)
#define RESPONSE_BUFFER_SIZE (MAXDATASIZE + 1)

FILE *fwrp;
char *response = malloc(RESPONSE_BUFFER_SIZE);
memset(response, '\0', RESPONSE_BUFFER_SIZE);

int readOffset = 0; // offset for reading the next chunk
int readCount; // count of readed characters/bytes

// below: return of fread() can be positive, 0 if no more data, or negative if error
while ((readCount = fread(response + readOffset, MAX_RESPONSE_SIZE - readOffset, 1, fpr)) > 0) {
    readOffset += readCount;
}

//Some unecessary code...

if (strstr(response, "file=")) {
    char* newFileName = strchr(response, '=');
    newFileName++;
    fwrp = fopen(newFileName, "w");
    data = false;
//...

【讨论】:

  • 感谢您的代码。你是对的,你是对的。我为什么要构建字段和响应的想法是该字段是 fread 的“未完成响应”。因为 fread 不会立即给我来自服务器的全部响应。所以我从 fread 读取,直到命令告诉我读取了来自服务器的整个响应。我的“响应”变量被构造,直到出现“\n”。所以我总是解析“响应行”,这使我的解析逻辑更容易一些。但在那里我会发布我的解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 2011-06-03
  • 2018-09-13
相关资源
最近更新 更多