2013-08-02 67 views
0

我想加载代理的列表,通过分割每行“:”分隔符,然后将其加载到一个结构:加载文件内容到结构

struct proxy_data { 
    ushort type; 
    char *ip; 
    uint16_t port; 
}; 


void load_proxies(char * proxy_file) 
{ 
    FILE * in; 
    struct proxy_data * temp = NULL; 
    if((in = fopen(proxy_file, "rt")) == NULL) 
    { 
     fprintf(stderr, "\nCan't open input file!\n"); 
     exit(0); 
    } 
    while(!feof(in)) 
    { 
     temp = malloc(sizeof(struct proxy_data)); 
     fscanf(in, "%s ",temp->type); 
     fscanf(in, "%s ",temp->ip); 
     fscanf(in, "%s ",temp->port); 
    }; 
    fclose(in); 
} 

但在编译时,我得到了许多错误。

我怎样才能加载每一行到结构?

+3

你会得到什么错误? – junix

+0

你的'struct'引用了其他地方分配的内存('proxy_data.ip'),因此将这个'struct'写入程序的一个实例并在另一个实例中读取将导致对未分配内存的无效引用,并且只会导致崩溃。你需要编组你的数据来写出指针的内容,并想出一种确定数据长度的方法。你不能像你试图的那样去做。 – trojanfoe

+0

@alk它来自哪里?它是'struct proxy_data'的'ip'成员。 – trojanfoe

回答

0

使用

struct proxy_data { 
unsigned short type; 
char *ip; 
unsigned short port; 
}; 

存在C无USHORT或UINT16。

或在程序的开始添加

#include <stdint.h> 

也不要忘记使用ip wizely这样你就不会被puting值之前分配IP获取无效引用未分配的内存在里面。阅读this

+0

和'proxy_data.ip'的内容??? – trojanfoe

+0

他谈到了comiler错误,我将它添加到@trojanfoe到答案 –

+0

是的,他在谈论编译器错误。一旦这些解决方案,他会问“为什么我的程序崩溃”? – trojanfoe

0

你不能只写struct s到文件,并期望他们在最简单的情况以外的任何其他工作。它们是特定于平台的(考虑整数大小和endian问题),并且如果它们包含指向其他内存部分的指针,则这些成员在读入时将成为孤立的,从而导致崩溃。

您试图解决的问题被称为marshalling,基本上可以如何将内部数据结构序列化为外部数据结构(即文件或网络)并对其进行反序列化。

如果您正在使用C++或Java(你是不是,它出现),那么可以考虑使用像Google Protocol Buffers,从而简化了这一过程的解决方案。

如果你必须写自己的解决方案,那么你就需要功能,比如说,从一个字符串转换成struct一个实例,例如:

int decode_proxy_data(const char *string, proxy_data *data) { 
    unsigned type, port; 
    char ip[32]; 
    if (sscanf(string, "%u %s %u", &type, ip, &port) == 3) { 
     data->type = (ushort)type; 
     data->ip = strdup(ip);  // This must be free()'d during destruction! 
     data->port = (uint16_t)port; 
     return TRUE; 
    } 
    return FALSE; 
} 

int encode_proxy_data(char *string, const proxy_data *data) { 
    sprintf(string, "%u %s %u", (unsigned)data->type, data->ip, (unsigned)data->port; 
    return TRUE; 
} 

然后,您可以读/写串到文件和这个代码几乎可以在任何平台上工作(当然,它没有经过测试)。

请注意,proxy_data.ip需要内存管理(即您必须调用free()以避免内存泄漏),但无论如何,无论您的编组问题如何,都是如此。

如果您有选择,请切换到C++。

+0

为什么它必须如此复杂?我只是想创建一个函数,它载入代理列表并检查它们的好坏。 – ShaMora

+0

@ShaMora编码*很复杂。否则任何人都可以这样做,我们将无法赚到这么多。 – trojanfoe

0

假设您的proxy_dile具有正确的结构(例如als值以文本形式存储),那么您的fscanf()错误。对于porttype应该

fscanf(in, "%hu ", &temp->...); 

当你要扫描一个短整数,ip你打电话之前fscanf()分配内存。此外,您不应该使用feof()fcanf()。搜索SO,你会发现很多关于这方面的信息。