使用malloc,结构和可能参数的问题

时间:2016-12-27 23:12:29

标签: c struct utf-8 segmentation-fault malloc

编辑:好的,我听说你们,我已经把我的代码部分给了我一些问题,编译了它并确保它仍然给了我相同的结果,这里是: 像以前一样,在for循环的第一个实例之后出现segfault strcpy(替换[j] - > utf8,strtok(data,“\ t”));再次感谢!

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

#define max_chars 45
#define max_UTF 5
#define max_ASCII 7
#define max_word_length 30
#define max_line_length 70
#define max_texto_line 5000

typedef struct {
char utf8[max_UTF];
char ascii_seq[max_ASCII];
int count;
} Replac; 


void getTable(FILE *f, char inputfile[],Replac **replace){
    char data[max_line_length];
    int j;
    f = fopen( inputfile, "r" );
    if (f == NULL) {
        fprintf(stderr, "Can't open input file %s!\n",inputfile);
        exit(1);
    }

    fgets(data,sizeof data,f);
    for(j=0 ; strcmp(data,"\n") ; fgets(data,sizeof data,f), j++){  
        if (feof(f)) {                                      
            break;
        }
        strcpy(replace[j]->utf8, strtok(data, "\t"));                   
        strcpy(replace[j]->ascii_seq, strtok(NULL, "\n"));
    }
    fclose(f);
}

int main( int argc, char *argv[] ){
    Replac *replace=malloc(max_chars * sizeof(Replac));
    FILE *fpr,*f,*fpw;
    int carprocess = 0;
    setlocale(LC_ALL,"pt_PT.UTF-8");
    setlocale(LC_COLLATE,"pt_PT.UTF-8");


    getTable(f,argv[1],&replace);
}

我正在复制字符的文本文件格式化为

UTFCHAR \tab asciichar

Á   'A

结束编辑

- ### - ### - #### - #### + ##### + #### P

所以我是一个初学者使用C,我已经尝试了所有我能想到的,这似乎是一个非常直接的事情,但因为我有这样的麻烦清楚地表明我有一些差距在我的知识...

我不会用完整的代码打扰你,因为它工作得很好,只是因为我想以不同的方式做事情,那就是麻烦开始的时候。

简而言之,我正在做一个程序,它收集一组UTF8类型的字符及其ascii替换,并将它们存储在一个结构中,如

 typedef struct {
char utf8[max_UTF];
char ascii_seq[mac_ASCII];
} Replac; 

然后在主要我做了像这样的malloc

Replac *replace=malloc(max_chars * sizeof(Replac));

如果我的思维过程是正确的,这将创建一个可用内存块,* replace指向起始地址。

然后我创建了一个函数来扫描几个UTF8字符及其替换并将它们存储在结构中,如

void getTable(FILE *f, char inputfile[],Replac **replace)

现在,在调试器之后,似乎我在一个完全不同的地址上创建替换**类型的新变量替换,但在该地址内部将值存储到我通过的原始malloced结构中PARAM。

之后我做了

strcpy(replace[0]->utf8, something I got from the table);

在调试器和搜索内存地址之后,我看到第一次执行此操作时,malloc结构的第一个位置确实填充了正确的数据。

接着是

strcpy(replace[0]->ascii_seq, corresponding ascii sequence to the previous UTF8 char);

并填充内存块中的下一个内存位置。

所以我在调试我的变量时得到的东西

地址替换=(Replac **)0xbf8104fc,包含0x0878a008

address * replace =(Replac *)0x0878a008包含整个结构 所以在地址0x0878a008内我得到了utf8字符的数据然后在地址0x0878a00d我得到了ascii seq。

循环的下一个实例的问题,到时候

strcpy(replace[1]->utf8, something I got from the table);

在该指令之后我得到了分段错误。

那你们觉得怎么样?我是否正确地接近了事情,并且我被语法或类似的东西搞砸了,还是我知识的基础有缺陷?

谢谢,祝节日快乐!

2 个答案:

答案 0 :(得分:0)

f = fopen( inputfile, "r" );
...
typedef struct 
{
    char utf8[max_UTF];
    char ascii_seq[max_ASCII];
    int count;
} Replac;
...
fgets(data,sizeof data,f);

您正在混合使用二进制和文本格式。

根据编译器的不同,sizeof(Replac)将为16。这包括始终sizeof(int)的{​​{1}}。如果大小不是4的倍数,则可能还有填充。

如果您的数据存储为文本,那么它将是这样的:

4

请注意,十进制格式的整数大小介于0到10之间,因此大小不固定。并且(或应该有)新行ABCDE\tABCDEFG123456\n 字符。

所以你不想读完16个字符。您想要为每条记录写入然后读取3行。例如:

\n

如果您正在阅读二进制文件,请以二进制文件打开该文件并使用ABCDE\n ABCDEFG\n 123456\n fwrite。例如:

fread

这完全取决于文件的创建方式。如果您自己编写文件,则显示用于编写数据的代码。

此外,ASCII是Unicode的子集。 ASCII中的f = fopen( inputfile, "rb" ); Replac data; fread(f, sizeof(data), 1, f); 与UTF8中的A完全相同。

答案 1 :(得分:0)

        strcpy(replace[j]->utf8, strtok(data, "\t"));                   
     

该指令后出现分割错误。

您刚刚将取消引用顺序弄错了。您首先用[j]下标,然后用->取消引用,就好像我们有一个指向Replac的指针数组一样。但是我们宁愿有一个指向Replac s数组(第一个元素)的指针,因此我们必须先取消引用该指针,然后再取消其下标i。 e。代替

                replace[j]->utf8

我们必须写

                (*replace)[j].utf8

或等价物

                (*replace+j)->utf8