简体   繁体   English

在读取文本文件之前为2D字符串数组分配空间

[英]Allocating space for a 2D string array before the text file is read

I'm reading from a large text file which contains a string followed by a newline. 我正在从一个大文本文件读取,该文件包含一个字符串,后跟一个换行符。 I'm using fgets to read each string and store them in a 2D string array as well as malloc to assign memory. 我正在使用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;

This uses a fixed value of MAX_WORD_LENGTH (10). 这使用MAX_WORD_LENGTH(10)的固定值。 However I'm now wanting to do it with with a non-fixed sized of words which is decided by finding the longest word in the text file it is given. 但是我现在想用一个不固定大小的单词来做到这一点,这个单词的大小是通过在给定的文本文件中找到最长的单词来决定的。 I have a function to find the longest word in the dictionary as well. 我也可以找到字典中最长的单词。 The problem is the malloc function needs max word length given to it, and the read_file function needs a dictionary array to read into - both of which happen before I can run the find longest word function. 问题是malloc函数需要为其赋予最大字长,而read_file函数需要将字典数组读入-两者均在我运行查找最长单词函数之前发生。

I guess the question is - how can I find the longest word in the text file before I malloc space for the dictionary, and before the actual text file is read into the dictionary. 我想问题是-在为字典分配空间之前以及在将实际文本文件读入字典之前,如何在文本文件中找到最长的单词。

I know I could just set max_word_length to be something ridiculously huge but that kind of defeats the point - I want the size of the space to be decided once it has found the max word length. 我知道我可以将max_word_length设置为一个可笑的巨大值,但是那有点不合时宜-我希望一旦找到最大字长,就可以决定空间的大小。

read file --> find longest word --> malloc space big enough for the longest word --> read file into new space is the aim. read file --> find longest word --> malloc space big enough for the longest word --> read file into new space是目标。

The following function goes through the file to count the length of all words and returns the length of the longest word. 以下函数遍历文件以计算所有单词的长度,并返回最长单词的长度。

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

Don't forget to rewind the file before processing it again. 不要忘记在再次处理文件之前倒带文件。

The file can be read and memory allocated at the same time. 可以同时读取文件和分配内存。 This allocates each pointer but could be modified to allocate a block of pointers for efficiency. 这分配了每个指针,但可以修改以分配一个指针块以提高效率。 Each pointer has just enough memory allocated for the length of the input. 每个指针都为输入的长度分配了足够的内存。

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM