C ++ CGI脚本,读取表单数据

时间:2012-04-26 06:01:17

标签: c++ c forms cgi

我一直在使用this tutorial制作C ++ CGI脚本。但是,当我尝试读取表单POST数据时,它没有编译:

  char* lpszContentLength = getenv("CONTENT_LENGTH");
  char* lpszBuffer;
  int nContentLength = atoi(lpszContentLength);

  lpszBuffer = malloc(lpszContentLength+1);  // allocate a buffer
  memset(lpszBuffer, 0, lpszContentLength+1);  // zero it out

  fread(lpszBuffer,1,lpszContentLength,stdin);  // get data

这是编译器的抱怨:

cgi.cpp: In function ‘int main()’:
cgi.cpp:12: error: invalid conversion from ‘char*’ to ‘size_t’
cgi.cpp:12: error:   initializing argument 1 of ‘void* malloc(size_t)’
cgi.cpp:12: error: invalid conversion from ‘void*’ to ‘char*’
cgi.cpp:13: error: ‘memset’ was not declared in this scope
cgi.cpp:15: error: invalid conversion from ‘char*’ to ‘size_t’
cgi.cpp:15: error:   initializing argument 3 of ‘size_t fread(void*, size_t, size_t, FILE*)’

其中ln 12是以“lpszBuffer”开头的那个。

我是C ++的新手,所以我不确定如何解决这个问题,或者为什么会发生这种情况。也许它只是过时的代码......我很乐意接受其他解决方案来从POST请求中读取数据。

修改: 我根据你们家伙的修正更新了代码。

  char* lpszContentLength = getenv("CONTENT_LENGTH");
  char* lpszBuffer;
  int nContentLength = atoi(lpszContentLength);

  lpszBuffer = (char*)malloc(nContentLength+1);  // allocate a buffer
  memset(lpszBuffer, 0, nContentLength+1);  // zero it out

  fread(lpszBuffer,1,nContentLength,stdin);  // get data

但是,我仍然从atoi获得了分段错误:

==23419== Invalid read of size 1
==23419==    at 0x498DA8C: ____strtol_l_internal (strtol_l.c:298)
==23419==    by 0x498D7EF: strtol (strtol.c:110)
==23419==    by 0x498AB60: atoi (atoi.c:28)
==23419==    by 0x8048899: main (in .../cgi.cpp.cgi)
==23419==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

这里有什么问题?我假设它与POST表单提交有关,如果POST是空白的......

2 个答案:

答案 0 :(得分:1)

这是C++的类型转换问题。 lpszBufferchar*,但malloc返回void*。所以你需要把它投射到char*。另请注意,您尝试将char*(lpszContentLength)用作整数值,这不是真的。这也必须在您的其他函数中更新 - 您已使用atoi函数更早地进行了转换;所以要使用这个值。

所以该行应该是

lpszBuffer = (char*)malloc(nContentLength+1);

最后,要使用memset,您必须在源文件的开头#include <string.h>

此外,作为良好的做法(特别是如果脚本运行了很长时间),完成后不要忘记free你的记忆。也就是说,当您不再使用它时,分配有malloc的任何内容都应该free调用它。因此,如果您在整个函数中使用lpszBuffer,则在函数末尾只需执行free(lpszBuffer);

答案 1 :(得分:0)

  

错误:从“char *”无效转换为“size_t”

这是因为尝试使用lpszContentLength(这是一个char*,在这种情况下是一个可能代表数字的字符串),作为size_t(通常是一个长整数) )。要解决此问题,首先需要将lpszContentLength转换为整数值。我建议使用strtol(),因为它会检测错误 - 您需要处理这些错误。

看一下教程,他们已经使用atoi()转换了它。您也可以使用nContentLength错误地尝试使用lpszContentLength的任何地方来解决此错误。他们的代码必须从未经过测试。

请注意,atoi()未检测到错误 - 因此,一旦完成本教程,通过适当的错误检查更改为strtol()将是一个很好的学习练习。


  

错误:无效转换为'void *'到'char *'

这是因为错过了对malloc返回值的强制转换为(char*)。在C ++中,需要强制转换:

lpszBuffer = (char*)malloc(convertedNumber+1); 

  

错误:未在此范围内声明'memset'

这是因为不包括memset的标头。 man page for memset告诉您需要添加:

#include <string.h>

  

错误:从“char *”无效转换为“size_t”

     

错误:初始化'size_t fread(void *,size_t,size_t,FILE *)'的参数3

这些都是由lpszContentLength是一串字符引起的,当它需要是一个整数类型时。请参阅上面的第一个错误。