【问题标题】:Reading words of lines and storing words at 3D Array读取行的单词并将单词存储在 3D Array
【发布时间】:2016-05-24 19:48:34
【问题描述】:

我正在处理这样一个问题,我有一个包含行单词的输入文件,我想用 3D-Array 逐行存储所有单词。但是我的代码似乎有问题,我认为我看不到发生分段错误的地方。这是我的代码:为了澄清:

"char *input" 是一个文件名 | “MAX_WORDS”是一个宏,相当于500 | “MAX_WLENGTH”是另一个相当于64的宏。

void func(char *input){
    FILE *fp;
    fp = fopen(input, "r");
    char buffer[MAX_WORDS][MAX_WORDS][MAX_WLENGTH];
    if(fp != NULL){
            int c;
            size_t i = 0;
            size_t x = 0;
            size_t y = 0;
            for(;;){
                    c = fgetc(fp);
                    if(c != EOF && c != '\n' && c != ' '){
                            if(i < MAX_WLENGTH -1){
                                    buffer[y][x][i++] = c;
                            }
                            continue;
                    }
                    if (i > 0){
                            buffer[y][x][i] = '\0';
                            if(c == '\n'){
                                    y++;
                                    x = 0;
                                    i = 0;
                            }
                            else if(c == ' '){
                                    x++;
                                    i = 0;
                            }
                    }
                    if(c == EOF){
                            break;
                    }
            }
            fclose(fp);
    }

    int i;
    int j;
    for(i = 0; i < MAX_WORDS; ++i){
         printf("\n");
         for(j=0; j < MAX_WORDS; ++j){
                printf("%s\t", strdup(buffer[i][j]));
         }
    }
 }

【问题讨论】:

  • char buffer[MAX_WORDS][MAX_WORDS][MAX_WLENGTH]; 堆栈太大。
  • @BLUEPIXY 谢谢。
  • 3D 数组是个坏主意。使用结构的动态数组会更好地为您服务,其中结构将代表每一行并包含一个 pointer-to-pointer-to-char 以指向该行中的每个单词。 (或者如果你有一个合理的每行最大字数,你可以使用一个简单的指针数组作为结构成员)。无论哪种方式,您都可以基于每个字进行分配,这比尝试使用 3D 字符数组(您发现它会很快超过即使是相对较少的行数和每行字数的堆栈大小)的内存效率要高得多

标签: c string file multidimensional-array


【解决方案1】:

您没有检查输入文件的字数是否超过 MAX_WORDS * MAX_WORDS(4096 个字)。因此,如果您的输入文件有更多单词,那么您正在尝试访问一个位置缓冲区 [y][x][i],其中 y 或 x 可能大于 64,这可能会导致分段错误。使用以下代码,而不仅仅是 y++;或 x++;

y++;
if(y == MAX_WORDS){
 break;
}

【讨论】:

  • 是的,当然。也谢谢你的建议。
猜你喜欢
  • 1970-01-01
  • 2020-08-26
  • 1970-01-01
  • 2021-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-23
相关资源
最近更新 更多