Я правильно использую этот динамический массив? - PullRequest
1 голос
/ 16 сентября 2011

Мне нужно создать динамический массив для хранения строк, которые я должен прочитать из трех файлов. Я новичок в C, и я не очень понимаю, как использовать указатели или выделить память. Я хотел бы знать, правильно ли я объявляю свой массив и правильны ли мои calloc() вызовы. Формат файла, который я буду использовать:

word1
word2
word3 (and so on)

Я просто предполагаю, что слова из файлов не длиннее 50 символов (включая \0).

В конце концов мне нужно будет отсортировать их, но мне нужно собрать их в массив, прежде чем я попробую это. Спасибо за любую помощь, которую вы можете оказать.


Вот что у меня есть ...

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

int countWords(FILE *f){
int count = 0;
char ch;
while ((ch = fgetc(f)) != EOF){
    if (ch == '\n')
        count++;
}
return count;
}


int main(void){

int i;
int wordCount = 0;
int stringLen = 50;

FILE *inFile;

inFile = fopen("american0.txt", "r");
wordCount += countWords(inFile);
fclose(inFile);

inFile = fopen("american1.txt", "r");
wordCount += countWords(inFile);
fclose(inFile);

inFile = fopen("american2.txt", "r");
wordCount += countWords(inFile);
fclose(inFile);

printf("%d\n", wordCount);


char **wordList = (char **) calloc(wordCount, wordCount * sizeof(char));
for (i = 0; i < wordCount; i++){
    wordList[i] = (char *) calloc(stringLen, stringLen * sizeof(char));
}

char ch;
int currentWord = 0;
int currentWordIndex = 0;
inFile = fopen("american0.txt", "r");
while ((ch = fgetc(inFile)) != EOF){
    if (ch == '\n'){
        currentWord++;
        currentWordIndex = 0;
    }
    else
        wordList[currentWord][currentWordIndex] = ch;
}
inFile = fopen("american1.txt", "r");
while ((ch = fgetc(inFile)) != EOF){
    if (ch == '\n'){
        currentWord++;
        currentWordIndex = 0;
    }
    else
        wordList[currentWord][currentWordIndex] = ch;
}
inFile = fopen("american2.txt", "r");
while ((ch = fgetc(inFile)) != EOF){
    if (ch == '\n'){
        currentWord++;
        currentWordIndex = 0;
    }
    else
        wordList[currentWord][currentWordIndex] = ch;
}

printf("%s\n", wordList[57]);
for (i = 0; i < wordCount; i++){
    free(wordList[i]);}

free(wordList);
return 0;
}

Ответы [ 3 ]

2 голосов
/ 16 сентября 2011
  • Вам не нужно приводить для возвращаемого значения calloc. Язык C указывает, что значение типа void* совместимо с любым типом указателя на объект. Добавление приведения может скрыть ошибку отсутствия заголовка, где объявлено calloc. В C ++ правила разные.

  • Функция calloc() принимает два аргумента: количество выделяемых элементов и размер каждого

    • В первом calloc вы пытались выделить wordCount элементов странного размера. Мне нравится использовать сам объект в качестве операнда для оператора sizeof
    • Во втором calloc вы пытались выделить 50 элементов размером 50 каждый. Но вы хотите только 1 элемент в каждом wordCount, верно? Кроме того, sizeof (char), по определению, 1, поэтому вам не нужно ничего умножать на него.

Попробуй вот так

char **wordList = calloc(wordCount, sizeof *wordlist);
for (i = 0; i < wordCount; i++) {
    wordList[i] = calloc(1, stringLen);
}
0 голосов
/ 16 сентября 2011

Попробуйте использовать структуру данных связанного списка.

Пример: http://www.macs.hw.ac.uk/~rjp/Coursewww/Cwww/linklist.html

это лучше подходит для ваших нужд.

0 голосов
/ 16 сентября 2011

В sizeof () вы должны использовать тип, который вы выделяете.Указатель на тип char отличается от типа самого char и может (и в большинстве случаев имеет) другой размер.Например:

char **wordList = (char **) calloc(wordCount, sizeof(char*));

Также вам не нужно умножать размер указателя на количество слов, calloc уже сделает это за вас.Вы также можете сделать это следующим образом:

char **wordList = (char **) malloc(wordCount * sizeof(char*));
...