【问题标题】:Using fprintf at a C++ code在 C++ 代码中使用 fprintf
【发布时间】:2011-10-31 09:54:57
【问题描述】:

我有一个奇怪的问题。当我尝试编译下面的代码时,它按预期工作而没有失败:

#include <iostream>
#include <Windows.h>

int main(){
       FILE *f = fopen("trystl.geo","w");
       fprintf(f,"Merge \"trystl.stl\";");
       fprintf(f,"\n");
       fprintf(f,"Surface Loop(2) = {1};");
       fprintf(f,"\n");
       fprintf(f,"Volume(3) = {2};");
       fclose(f);
       return 0;
}

但是当我尝试将此程序连接到具有 FLTK 用户界面的按钮时,它给了我一个断言运行时错误。我的代码段:

void UserInterface::cb_m_BtnSTLToGEOConverter_i(Fl_Button*, void*){
    //OnSTLToGEOConvert();
       FILE *f = fopen("trystl.geo","w");
       fprintf(f,"Merge \"trystl.stl\";");
       fprintf(f,"\n");
       fprintf(f,"Surface Loop(2) = {1};");
       fprintf(f,"\n");
       fprintf(f,"Volume(3) = {2};");
       fclose(f);
}
void UserInterface::cb_m_BtnSTLToGEOConverter(Fl_Button* o, void* v){
    ((UserInterface*)(o->parent()->parent()->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_m_BtnSTLToGEOConverter_i(o,v);   
}

当用户按下按钮时,我希望程序创建一个名为 trystl.geo 的文件并执行所示操作。但是当编译打开程序并点击按钮时,它会说:

调试断言失败!

程序:*.......\src\fprintf.c 第 55 行:

表达式:(str!NULL)

中止重试或忽略...

我正在使用 Visual Studio 2010。

【问题讨论】:

  • 您将第一个 sn-p 与第二个进行比较,就好像它们是等价的,但第二个包含一个单独的函数,其中包含非常可疑的函数结果取消引用序列。我会把你的精力集中在那里,然后用不那么疯狂的testcase 回到我们这里。
  • @Tomalak:仍然,fprintf 部分在两个 sn-ps 中是相同的,并且它不依赖于任何参数,也不依赖于 this(实际上,只使用字符串文字),所以理论上它应该可以工作;对于这种故障,唯一想到的就是堆栈损坏。
  • @Matteo:是的,鉴于荒谬的取消引用堆栈/堆损坏(或简单地取消引用错误的东西)显然是问题所在。关键是,第二个 sn-p 的问题几乎可以肯定与第一个完全无关。如此盲目地忽视其中的差异,这几乎是令人反感的。
  • @Italia。这才是重点。所有“parent()”的函数都是正确的。问题应该出在不同的地方。
  • ((UserInterface*)o-&gt;parent()-&gt;parent()-&gt;parent()-&gt;parent()-&gt;parent()-&gt;parent()-&gt;parent()-&gt;user_data()))-&gt;cb_m_BtnSTLToGEOConverter_i(o,v); 这会让我做噩梦:/(显然会杀死 FF 下 SO 的格式:D)

标签: c++ visual-c++ user-interface button fltk


【解决方案1】:

错误很简单:VC++ 中 fprintf.c 中的第 55 行是 _VALIDATE_RETURN( (str != NULL), EINVAL, -1);,而 strFILE* 参数(虽然我见过更好的命名变量)。

对于好奇的(我是)_VALIDATE_RETURN定义如下:

#define _VALIDATE_RETURN( expr, errorcode, retexpr )                           \
    {                                                                          \
        int _Expr_val=!!(expr);                                                \
        _ASSERT_EXPR( ( _Expr_val ), _CRT_WIDE(#expr) );                       \
        if ( !( _Expr_val ) )                                                  \
        {                                                                      \
            errno = errorcode;                                                 \
            _INVALID_PARAMETER(_CRT_WIDE(#expr) );                             \
            return ( retexpr );                                                \
        }                                                                      \
    }

所以最好在尝试写入不存在的文件描述符之前检查您的 fopen() 调用是否成功。

【讨论】:

  • 感谢您的帮助,您是对的。我的程序不能调用 fopen()。我也尝试将指针初始化为全局变量,它也没有用。我想知道为什么会这样。我不能用 GUI 初始化一个新文件吗?
  • 没那么简单。没有理由不能通过 GUI 程序创建新文件。可能的解释是您的程序中存在错误,并且在错误发生后其他事情停止工作。该错误位于您尚未发布的代码中。祝你好运。
【解决方案2】:

好的,我找到了解决方案。唯一的问题是,如果您不在程序中输入整个路径,则文件不会被打开。我换了

FILE *f = fopen("trystl.geo","w");

FILE *f = fopen("c:/Users/anypath/trystl.geo","w");

有效!

感谢您的帮助!

【讨论】:

  • 可能是因为我之前写的:“如果可执行文件的当前目录不能被具有“正常”权限的可执行文件写入,就会发生这种情况”
  • @Matteo Italia 这没有任何意义。如果可执行文件无法使用相对文件路径访问文件,它将无法使用绝对路径进行访问。最可能的原因是 Emre 假设工作目录位于其他位置而不是实际位置..
  • @Voo:这正是我要说的...... <_>
猜你喜欢
  • 2012-06-24
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-24
  • 2013-10-09
相关资源
最近更新 更多