【问题标题】:Allocating space for a 2D string array before the text file is read在读取文本文件之前为二维字符串数组分配空间
【发布时间】:2015-11-17 12:41:12
【问题描述】:

我正在读取一个大文本文件,其中包含一个字符串,后跟一个换行符。我正在使用 fgets 读取每个字符串并将它们存储在 2D 字符串数组中,并使用 malloc 来分配内存。

void read_file (char **dictionary, char * argv[])

{

FILE * file_name;
int i = 0, word_count = 0, c;

    file_name = fopen(argv[0], "r");
    if (file_name == NULL)
        {
            printf("Cannot open file");
        }
    while (fgets(dictionary[i], MAX_WORD_LENGTH, file_name))
        {
            dictionary[i][strlen(dictionary[i]) - 1] = '\0';
            word_count++;
            i++;
        }
    printf("\n%d words scanned in from: %s\n", word_count, argv[0]);
    fclose(file_name);
}

char ** AllocateDictionaryMemory (void)

{

int i;

char **p = malloc(MAX_WORDS * sizeof(*p));

        for (i = 0; i < MAX_WORDS; i++)
        {
            p[i] = malloc(MAX_WORD_LENGTH + 1);
        }
        if (p == NULL)
        {
            printf("Failed to allocate 2D string array space\n.");
        }

return p;

这使用固定值 MAX_WORD_LENGTH (10)。但是,我现在想用不固定大小的单词来做这件事,这是通过在给出的文本文件中找到最长的单词来决定的。我也有在字典中查找最长单词的功能。问题是 malloc 函数需要给它最大字长,而 read_file 函数需要一个字典数组来读入——这两者都发生在我可以运行查找最长单词函数之前。

我想问题是 - 在我为字典分配空间之前,以及在将实际文本文件读入字典之前,如何在文本文件中找到最长的单词。

我知道我可以将 max_word_length 设置为大得离谱的值,但这有点不合时宜 - 我希望在找到最大字长后确定空间的大小。

read file --&gt; find longest word --&gt; malloc space big enough for the longest word --&gt; read file into new space 是目标。

【问题讨论】:

  • 请缩进代码。
  • 在我看来是缩进的? :s

标签: c arrays string malloc


【解决方案1】:

下面的函数遍历文件,统计所有单词的长度,返回最长单词的长度。

int findLongestWord(FILE *fin)
{
    int c, i=0, longest= 0
    while ((c=fgetc(fin))!=EOF)
    {
        if (isspace(c)) {
            if (i>longest) longest= i;
            i= 0;
        }
        else i++;
    }
    if (i>longest) longest= i;    // suppose last word was longest..
    return longest;
}

在再次处理之前不要忘记倒带文件。

【讨论】:

  • '倒带;'文件?我可以关闭并重新打开它,对吗?
【解决方案2】:

可以同时读取文件和分配内存。这会分配每个指针,但可以修改为分配一个指针块以提高效率。每个指针都为输入的长度分配了足够的内存。

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

char** readwords( FILE *pf, int *wordcount);

int main( int argc, char *argv[])
{
    FILE *wordfile = NULL;
    char **s = NULL;
    int wordsize = 0;
    int each = 0;

    if ( argc < 2)
    {
        printf ( "program needs a filename as in:\nprogram filename\n");
        return 1;
    }

    if ( ( wordfile = fopen(argv[1], "r")) == NULL)
    {
        printf("Cannot open file");
        return 2;
    }

    s = readwords( wordfile, &wordsize);
    fclose ( wordfile);

    if ( s == NULL)
    {
        printf ( "no words in array\n");
        return 0;
    }

    for ( each = 0; each < wordsize; each++)
    {
        printf ( "%s\n", s[each]);
    }

    while ( wordsize) {
        wordsize--;
        free ( s[wordsize]);
    }
    free ( s);

    return 0;
}

char** readwords( FILE *pf, int *count)
{
    char** words = NULL;//NULL so realloc will work on the first call
    char** temp = NULL;
    char input[200] = "";

    //read each line into fixed size array
    while ( fgets ( input, sizeof ( input), pf))
    {
        //remove trailing newline if present
        input[strcspn ( input, "\n")] = '\0';
        //increment count of words
        *count = *count + 1;
        //allocate another pointer
        if ( ( temp = realloc ( words, *count * sizeof ( char *))) == NULL)
        {
            //if realloc fails 'words' should still be valid
            printf ( "realloc failed\n");
            *count = *count - 1;
            return words;
        }
        words = temp;//assign temp back to words
        //allocate memory to the pointer
        if ( ( words[*count - 1] = malloc ( strlen ( input) + 1)) == NULL)
        {
            printf ( "malloc failed\n");
            *count = *count - 1;
            return words;
        }
        strcpy ( words[*count - 1], input);
    }
    return words;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2012-11-19
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多