2012-05-22 48 views
0

即时尝试从文件中复制一些文本并将它们保存在结构成员中,我在cmd.exe上运行我的程序并崩溃,但是当我在代码块或Visual Studio上运行它时作品,无法在cmd.exe上运行此程序

#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 | 3月15日2001|5555555|[email protected]|123街道

没有任何人知道为什么它崩溃时我尝试在cmd.exe上运行它?

+0

您的意思是,当您运行编译的可执行文件时,它会崩溃,但是当您在Visual Studio中运行代码时,它的工作原理是什么? –

+1

你为什么写'char nom ['']'? –

+0

你是对的@EitanT – user1193803

回答

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); 
+0

所以解决的办法是将'tam + 1'传递给'malloc' –

0

此:

char nom[' ']; 

是很奇怪的代码,它几乎肯定不会做你希望它是什么。我希望听到这段代码的动机。

它基本上将nom声明为一个字符数组,其长度由字符SPACE的整数值给出。假设一个ASCII的机器,这将等同于:

char nom[32]; 
+3

它确实很奇怪,但它并不能解释程序崩溃的原因。 –

1

我不知道为什么它的工作原理在Visual Studio,但在崩溃CMD线。但是,也有在你的代码的几个问题:

 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; 
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)