Проблема с приведением типа массива строк в C - PullRequest
0 голосов
/ 30 июня 2010

Я пытаюсь прочитать большой список английских слов из текстового файла в массив строк. Количество слов - 2016415, а максимальная длина слова - 69 символов.

Если я определяю массив как «char data [2016415] [70];», тогда я получаю переполнение стека при запуске программы.

Так что я пытаюсь использовать calloc () вместо этого, однако я не могу понять, как я должен привести его к типу, чтобы он стал эквивалентен "char data [2016415] [70];".

Следующая программа возвращает предупреждение "передача аргумента 1 из` fgets 'делает указатель из целого числа без приведения "во время компиляции. И когда я его выполняю, возникает проблема «Exception: STATUS_ACCESS_VIOLATION».

Вы можете мне помочь?

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

int main(void){
char *data;  //data[2016415][70];

int i;
FILE *fsol;

fsol = fopen("C:\\Downloads\\abc\\sol2.txt","r");

data = (char*) calloc(2016415,70);

for(i=0;i<2016415;i++){
    fgets(data[i] , 70 , fsol);
}

fclose(fsol);

return 0;

}

Ответы [ 5 ]

1 голос
/ 30 июня 2010

calloc просто выделяет большой объем памяти, а не массив указателей на другие массивы.

fgets ожидает указатель на область памяти, в которую он должен записать свои данные.

Таким образом, вместо того, чтобы дать ему содержимое data[i], вы хотите дать ему адрес data[i], чтобы он мог поместить туда свои вещи.

fgets(&data[i], 70, fsol);

Возможно, вам также понадобится настроить цикл так, чтобы он увеличивался на 70 с лишним символов за раз, а не на один.

1 голос
/ 30 июня 2010

Хорошо, извините за предыдущее предложение. Я забыл, насколько ужасными могут быть массивы. Этот тест проверен с небольшим набором данных из 10 слов, но он должен масштабироваться до вашего количества слов. Обратите внимание, что fgets (), похоже, вставляет окончания строк как часть предыдущего слова.

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

#define MAX_WORD_CNT 2016415
#define MAX_WORD_LEN 70

int main(void)
{
    char *data;  //data[2016415][70];

    int i;
    FILE *fsol;

    fsol = fopen("C:\\Downloads\\abc\\sol2.txt","r");

    data = (char*) calloc(MAX_WORD_CNT, MAX_WORD_LEN);

    // check for valid allocation
    if (data == NULL)
    {
        return 1;
    }

    for(i=0; i<MAX_WORD_CNT; i++)
    {
        fgets(&data[i * MAX_WORD_LEN], MAX_WORD_LEN, fsol);
    }

    fclose(fsol);

    return 0;
}
0 голосов
/ 30 июня 2010

Ответ прост: вы НЕ разыгрываете его.Приведение результатов malloc / calloc / и т. Д.не имеет цели, но может иметь побочный эффект - скрыть серьезную ошибку, если вы забыли включить stdlib.h.Тип возврата этих функций распределения, который равен void *, будет автоматически приведен к тому, что вам нужно.

Если вы действительно хотите знать тип, это (char (*)[70]).Но, пожалуйста, не запутывайте свою программу, написав это.(Если вы на самом деле не пишете C ++, в этом случае вы должны были пометить свой вопрос C ++, а не C, или, что еще лучше, использовать new.)

0 голосов
/ 30 июня 2010

data - указатель на символ (также адресуемый как массив символов), поэтому data[i] - это один символ.fgets ожидает указатель на символ, но вы передаете ему один символ;вот почему вы получаете предупреждение, вы пытаетесь использовать символ (целое число) в качестве указателя.

Когда вы запускаете программу, она принимает этот единственный аргумент char и интерпретирует его как указатель насимвол, следовательно, нарушение прав доступа, потому что значение этого символа не является допустимым адресом.

Итак, в вашем цикле вы должны передать fgets указатель в data и увеличить егона 70 с каждой итерацией.Вы можете использовать форму «указатель на элемент массива» &data[i] и приращение i, или простую форму указателя, с другой переменной указателя, изначально установленной на data, и сама увеличивающейся.

0 голосов
/ 30 июня 2010

Вот как бы я выделил массив

char **data = malloc(MAX_WORD_CNT * sizeof(char *));
for(int i = 0; i < MAX_WORD_CNT; i++)
    data[i] = malloc(MAX_WORD_LEN);

вы можете добавить проверку ошибок для malloc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...