0

ファイルからいくつかのテキストをコピーして構造体メンバーに保存しようとすると、cmd.exeでプログラムを実行するとクラッシュしましたが、コードブロックまたはVisualStudioで実行すると機能します。

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

struct AMIGOS 
{ 
    char nom[' '];
    char apellido[' '];
    char nompila[' '];
    char tel[' '];
    char correo[' '];
    char dir[' '];
    char fecha[' ']; 
};

int main()
{
    struct AMIGOS reg;
    char registro[128];

    char**datos;
    char*dato;
    datos = (char**)malloc(10*sizeof(char**));
    int tam;
    int i=0;

    FILE* pt = fopen("arch.txt","r");
    if(pt==NULL)
    {
        printf("filenotfound\n");
    }
    else
    {
        while(fgets(registro,128,pt))
        {
            dato = strtok(registro,"|");
            while(dato)
            {
                tam = strlen(dato);
                datos[i] = (char *)malloc(tam);
                memcpy(datos[i],dato,tam);
                datos[i][tam]=0;
                i++;
                datos[i]=0;
                dato = strtok(0,"|");
            }    
        }
        strcpy(reg.nom,datos[0]);
        strcpy(reg.apellido,datos[1]);
        strcpy(reg.nompila,datos[2]);
        strcpy(reg.fecha,datos[3]);
        strcpy(reg.tel,datos[4]);
        strcpy(reg.correo,datos[5]);
        strcpy(reg.dir,datos[6]);

        printf("%s\n",reg.nom);
        printf("%s\n",reg.apellido);
        printf("%s\n",reg.nompila);
        printf("%s\n",reg.fecha);
        printf("%s\n",reg.tel);
        printf("%s\n",reg.correo);
        printf("%s\n",reg.dir);
    }    
}

ファイルのテキスト:

ケビン|クラーク|ns|2001年3月15日|5555555| l@mail.com|123ストリート

cmd.exeで実行しようとするとクラッシュする理由を誰かが知っていますか?

4

4 に答える 4

2

これは、配列の終わりを超えて書き込んでいます。

tam = strlen(dato);
datos[i] = (char *)malloc(tam);
memcpy(datos[i],dato,tam);
datos[i][tam]=0;                 <---- 'tam -1' is the last element

ヌルターミネータを格納するために文字を追加する必要があります。または、次を使用することもできますstrdup()

datos[i] = strdup(dato);
于 2012-05-22T08:51:58.130 に答える
1

Visual Studioで動作する理由はわかりませんが、CmdLineでクラッシュします。ただし、コードにはいくつかの問題があります。

        tam = strlen(dato); 
        datos[i] = (char *)malloc(tam); //You are not allocating memory for '\0' character
        memcpy(datos[i],dato,tam);
        datos[i][tam]=0; //So this is effectively an array out of bound write

する必要があります

        tam = strlen(dato); 
        datos[i] = (char *)malloc(tam+1); 
        memcpy(datos[i],dato,tam);
        datos[i][tam]=0; 
于 2012-05-22T08:53:58.487 に答える
1

ここにいくつかの問題があります:

datos = (char**)malloc(10*sizeof(char**));

あなたは実際に意味します:

datos = (char**)malloc(10*sizeof(char*));

(次の通常のCイディオムに従います:

var = malloc(n * sizeof *var);

この間違いを避けるでしょう。実際には、サイズは同じである可能性がありますが、原則として間違っています。mallocまた、の結果をキャストすることもCで眉をひそめることに注意してください。)

tam = strlen(dato);
datos[i] = (char *)malloc(tam);
memcpy(datos[i],dato,tam);
datos[i][tam]=0;

バッファがオーバーフローしています。あなたはメモリのバイトを割り当てtam、それからそれにバイトをコピーtamしました、しかしそれからあなたはそれをNUL終了しようとします。tam + 1バイトを割り当てる必要があります。

他のアドバイスとして:

  • の使用strcpyは安全ではありません。トークン化された入力によってこれらのバッファもオーバーフローしないことを保証することはできません。
  • fgets(registro,128,pt)としてより良いでしょうfgets(registro, sizeof registro, pt)
于 2012-05-22T08:54:07.300 に答える
0

これ:

char nom[' '];

非常に奇妙なコードですが、ほぼ確実に期待どおりの動作をしません。このコードの動機を聞いてみたいと思います。

基本的にnomは文字の配列として宣言され、その長さは文字の整数値で指定されますSPACE。ASCIIマシンを想定すると、これは次のようになります。

char nom[32];
于 2012-05-22T08:47:18.333 に答える