2015-11-03 44 views
3

嘿家伙我是一个相对较新的程序员在C,我试图简单地将输入文件中的内容打印到我的屏幕上。我必须使用动态内存分配,我面临的问题是如果字符串中的字母数大于8,它会覆盖它。动态内存分配从输入文件的数组字符串

int main(){ 
FILE *input = fopen("inpit.txt","r"); 
int b; 
char **aPtr; 
int i = 0; 
int j = 0; 
fscanf(input,"%d",&b); //takes first value from input file which tells me number of strings in the file 
aPtr = (char **)malloc(sizeof(char *)*b); 
for(i=0;i<b;i++) { 
    aPtr[i]=(char *)malloc(sizeof(char)); 
} 
for(i = 0;i < b;i++){ 
    fscanf(input,"%s",&aPtr[i]); 
} 
for(i = 0;i < b;i++){ 
    printf("Address %d = %d\n",i,&aPtr[i]); 
} 

for(i = 0;i < b;i++){ 
    printf("%s\n",(aPtr+i)); 
} 
return 0; } 

我输入到文件inpit1.txt是:

5 
grapefruit 
apple 
Banana 
monkey 
orange 

如果我运行该文件。除了葡萄柚之外,一切都会打印出来。这将被覆盖到grapefruapple。

任何帮助,将不胜感激。先谢谢你。

+0

你可能已经得到了更好的结果,如果你没有在C项目寻找C++文档!不要为外语添加标签!并且不要将'malloc'和朋友的结果放在C中! – Olaf

+1

哦,并正确缩进你的代码! 'main'的签名是错误的!写100次:“C不是C++不是C!” – Olaf

+0

@Olaf写100遍:“C不是C++不是C!”哈哈好:) – LBes

回答

2

你必须与你的malloc一个问题,只分配了一个字符的位置:

aPtr[i]=(char *)malloc(sizeof(char)); 

尝试给定的尺寸添加到它:

aPtr[i]=(char *)malloc(sizeof(char)*20); 

它应该更好地工作

关于铸造malloc()的注意事项: 铸造malloc()在c中是没有必要的(除非处理超旧的st [1989年以前]),并可以隐藏错误。 void*会自动提升为任何其他指针类型。 但是,如果编译为C++,这很有用,因为你的问题包括C和C++,我认为这很好的告诉你。

编辑:有关演员的其他信息malloc()我刚刚发现这个受保护的问题here。随时检查一下。

你也需要检查malloc()是成功的(结果是!=NULL

最后你的printf是不正确的,应该是printf("%s\n", aPtr[i]);

2

问题,我看到:

  1. 你是没有为aPtr[i]分配足够的内存。

    aPtr[i]=(char *)malloc(sizeof(char)); 
    

    分配内存只有一个char。举行一个字符串是不够的。你需要的东西,如:

    int arraySize = 20; // Make it large enough 
    aPtr[i] = malloc(arraySize); // No need to use sizeof(char). 
              // It is always 1 
    
  2. 确保当你读的字符串,你不溢出数组的大小。相反的:

    fscanf(input,"%s",&aPtr[i]); 
    

    使用:

    fscanf(input,"%19s", aPtr[i]); 
    //     ^^^ Remove the & operator. That is wrong. 
    //   ^^^ Add size to prevent overflow. 
    
  3. 您使用了错误的参数给printf功能。相反的:

    printf("%s\n",(aPtr+i)); 
    

    使用

    printf("%s\n", *(aPtr+i)); 
    //   ^^^ Missing pointer dereferencing operator 
    

    printf("%s\n", aPtr[i]); 
    
0

对你的问题的第一个评论是正确的,在这个问题的心脏。
malloc(sizeof(char))真的只是malloc(1)

您所做的一切是...

分配n字符数组的指针

aPtr = (char **)malloc(sizeof(char *)*b); 

分配单个字符列表中的每个指针

for(i=0;i<b;i++) { 
    aPtr[i]=(char *)malloc(sizeof(char)); 
} 

将未知长度的字符串复制到分配给每个p的内存中在列表中输入。

for(i = 0;i < b;i++){ 
    fscanf(input,"%s",&aPtr[i]); 
} 

分配给每个字符指针的内存可能与分配给其前任的内存接近或连续。后续写入可能会覆盖前面字符串的某些部分。就你的例子而言,连续分配的记忆块之间似乎存在足够的空隙,只有'葡萄柚'条目足够长时间才能被其邻居明显践踏。

0

你去那里:)(我试过在评论中讲解)

int main() { 

    FILE * pFile; 
    char * buffer = NULL; 
    size_t size = 0; 
    ssize_t line_length; 

    pFile = fopen("inpit.txt", "r"); 
    if (pFile != NULL) { 
     int number_of_lines; 
     fscanf(pFile, "%d", &number_of_lines); 

     //create charcter pointers array to hold each line 
     char* strings[number_of_lines]; 

     int i = -1; 
     while ((line_length = getline(&buffer, &size, pFile)) != -1) { 
      if (i != -1) { // skips first line because its number of lines (5) 
       strings[i] = malloc(line_length * sizeof(char)); //allocate memory for the line 
       sprintf(strings[i], "%s", buffer); //copy line from buffer to allocated space 
      } 
      //incase file has more than it said 
      if (i++ >= number_of_lines) { break; } 
     } 

     //Test print 
     for (i = 0; i <= number_of_lines; i++) { 
      printf("%s", strings[i]); 
     } 
     printf("\n"); 

     fclose(pFile); 
     if (buffer) { free(buffer); } 
    } 
}