【问题标题】:Data written in file using glib使用 glib 将数据写入文件
【发布时间】:2015-11-30 15:26:12
【问题描述】:

我有一个代码,它使用 g_file_set_contents 在文件中写入多个长度为 <length> 的字符。当我打开文件时,我看到一些奇怪的字符,它们似乎是 ASCII 码,例如 @&@@。我假设数据可能以 ASCII 格式写入,从二进制转换,所以我使用了一个函数将 ASCII 转换为二进制。执行后我仍然没有得到任何解决方案。
这是代码

#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv) 
{

 FILE *file = g_fopen("Multicore","w");
 gchar *contents = 00001111;
 gchar **contents1 = NULL;
 GError *err = NULL;
 g_file_set_contents ("Multicore", &contents, 8, &err);
 g_assert ((contents == NULL && err != NULL) || (contents != NULL && err == NULL));
 if (err != NULL)
  {
    g_assert (contents == NULL);
    fprintf (stderr, "Unable to read file: %s\n", err->message);
    g_error_free (err);
  } 
 else
  {
    g_assert (contents != NULL);
  }
  int p = g_ascii_digit_value(contents);
  if (g_ascii_isdigit (contents))
    return contents - '0';
  return -1;
  g_printf(" The output is %c \n", contents);
  return 0;
}

我得到正确的输出

输出为 00001111

【问题讨论】:

  • 您可能希望使用 -Wall -Werror 编译并在我构建您的代码时修复警告,我收到大约 12 个警告,这些警告看起来严重到足以产生意外结果
  • 我使用这个命令。 gcc pkg-config --cflags glib-2.0 new_compile.c pkg-config --libs glib-2.0 我应该把 -Wall 和 -Werror 放在命令的末尾吗?显然我得到了大约 12 13 个之前没有出现的错误。
  • glibc 通常指的是 GNU libc。 glib 是来自 GTK 的一个包(无需 GUI 即可使用)

标签: c glib


【解决方案1】:

你确实有很多错误。如建议的那样,使用警告进行编译将有助于将您的注意力引导到需要修复的内容上。首先解决最重要的问题(编译器无法找到g_fopen),例如:

debug.c:12:2: warning: implicit declaration of function ‘g_fopen’ [-Wimplicit-function-declaration]
  FILE *file = g_fopen("Multicore","w");
  ^
debug.c:12:15: warning: initialization makes pointer from integer without a cast [enabled by default]
  FILE *file = g_fopen("Multicore","w");
           ^

这告诉您缺少包含文件。快速检查会告诉您包括:`

#include <glib-object.h>
#include <glib/gstdio.h>

修复包含后,您会发现一些额外的警告需要解决:

debug.c: In function ‘main’:
debug.c:13:20: warning: initialization makes pointer from integer without a cast [enabled by default]
gchar *contents = 00001111;
                    ^
debug.c:16:2: warning: passing argument 2 of ‘g_file_set_contents’ from incompatible pointer type [enabled by default]
g_file_set_contents ("Multicore", &contents, 8, &err);
^
In file included from /usr/include/glib-2.0/glib.h:50:0,
                from debug.c:1:
/usr/include/glib-2.0/glib/gfileutils.h:91:10: note: expected ‘const gchar *’ but argument is of type ‘gchar **’
gboolean g_file_set_contents (const gchar *filename,
        ^
debug.c:28:3: warning: passing argument 1 of ‘g_ascii_digit_value’ makes integer from pointer without a cast [enabled by default]
int p = g_ascii_digit_value(contents);
^
In file included from /usr/include/glib-2.0/glib.h:81:0,
                from debug.c:1:
/usr/include/glib-2.0/glib/gstrfuncs.h:96:23: note: expected ‘gchar’ but argument is of type ‘gchar *’
gint                  g_ascii_digit_value  (gchar    c) G_GNUC_CONST;
                    ^
/usr/include/glib-2.0/glib/gstrfuncs.h:67:19: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
((g_ascii_table[(guchar) (c)] & G_ASCII_DIGIT) != 0)
                ^
debug.c:29:7: note: in expansion of macro ‘g_ascii_isdigit’
if (g_ascii_isdigit (contents))
    ^
debug.c:30:5: warning: return makes integer from pointer without a cast [enabled by default]
    return contents - '0';
    ^
debug.c:32:3: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘gchar *’ [-Wformat=]
g_printf(" The output is %c \n", contents);
^

依次解决每个问题会让您的程序编译时只警告未使用的变量,这不会影响其操作:

#include <glib.h>
#include <glib-object.h>
#include <glib/gstdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main (int argc, char **argv)
{

    FILE *file = g_fopen ("Multicore", "w");
    gchar *contents = "00001111";
    gchar **contents1 = NULL;
    GError *err = NULL;
    g_file_set_contents ("Multicore", contents, 8, &err);
    g_assert ((contents == NULL && err != NULL)
            || (contents != NULL && err == NULL));
    if (err != NULL) {
        g_assert (contents == NULL);
        fprintf (stderr, "Unable to read file: %s\n", err->message);
        g_error_free (err);
    } else {
        g_assert (contents != NULL);
    }
    int p = g_ascii_digit_value (*contents);
    if (g_ascii_isdigit (*contents))
        return *contents - '0';
    return -1;
    g_printf (" The output is %c \n", *contents);
    return 0;
}

使用

$ ./bin/debug

输出

$ cat Multicore
00001111

根据需要,没有额外或奇怪的字符。

启用警告的完整编译字符串

我正在使用的笔记本电脑(openSuSE 13.1)上的完整编译字符串使用pkg-config 来保护必要的包含/库路径以及库本身。使用的编译字符串是:

gcc -Wall -Wextra -Ofast -o bin/debug debug.c \
`pkg-config --cflags --libs gtk+-2.0`

如果您没有pkgconfig,则扩展的完整编译字符串(为了便于阅读而插入行继续)将是:

gcc -Wall -Wextra -Ofast -o bin/debug debug.c -pthread -I/usr/include/gtk-2.0 \
-I/usr/lib64/gtk-2.0/include -I/usr/include/pango-1.0 -I/usr/include/atk-1.0 \
-I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/libdrm \
-I/usr/include/libpng16 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng16 \
-I/usr/include/pango-1.0 -I/usr/include/harfbuzz -I/usr/include/pango-1.0 \
-I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/freetype2 \
-lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 \
-lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lfontconfig \
-lfreetype

【讨论】:

  • 嗨,大卫——我明白了,你平时做得很好。 OP 向 [我] 询问 -Wall 的位置。我打算做一个类似的“全方位服务”清理并发布它,但现在,没有必要。我会添加一个关于如何创建合理的 Makefile 的附录。也许,您可以将其添加到您的帖子中,因为我不值得为此单独回答
  • 好的,我会发布编译字符串。我使用了一些不同的系统,它通过构建脚本在每个目录的基础上创建一个 makefile-on-the-fly 并且本地 bldflags 包含必要的包含和 lib 路径,所以我不'没有完整的 makefile :)
  • 我做了一些非常相似的事情 [实际上非常相似——构建用 perl 编写的与scons 相似的系统]。如果我遇到你 IRL,我可能会称你为“朋友”:-)。我只为 SO 说 Makefiles。我已经建立了一个 rules.mk,但它仍然需要一些我的 perl 基础设施,这就是我没有发布它的原因。
  • 令人尴尬地不完整,但我将 makefile-on-the-fly 的副本放在pastebin - gcc build system (alias to 'g')。我只是在当前目录中删除了一个bldflags 文件,其中包含该项目所需的其他标志/库。对于我的 gtk2 目录,我在 bldflags 文件中包含以 -pthread ... 开头的所有内容。给我任何建议:)
  • 这需要一点时间,但我会看看它。我一直在构建我的 perl 脚本基础设施(例如 250,000 行)。构建部分是 10,000 行,但核心库是 30,000 行。它使用单个命令安装,但是......不太便携。但是,我确实发布了构建脚本的核心定义文件。这些是 .ini 样式格式,工作方式类似于系统的配置文件 请参阅 pastebin.com/Pae5RgD8 每个程序都有自己的 [program_name] 部分,并且构建可以从任何目录完成,因为构建系统知道顶级源目录的完整路径
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 2017-04-15
  • 2013-12-29
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多