Создание массива строк с использованием malloc в C

Я совсем новичок в C и только что узнал о распределении динамической памяти с использованием malloc, realloc, calloc и free.

Я хочу создать небольшую программу, которая принимает число int в качестве количества строк, которые будут переданы, а затем "сканировать" их все. Затем поиграйте с этими струнами. Например, найдите наиболее часто встречающееся и распечатайте его.
Например, когда я запускаю программу и набираю:
5
car house dog tree tree
Он должен напечатать:
tree 2

Мне нужен scanf-printf, потому что это методы ввода / вывода, с которыми я наиболее знаком на данный момент.
Мой код:

int main (){

int N,i,j ;

char *array;

int *freq;


 scanf("%d",&N);

 array = (char*)calloc(N,sizeof(char*));
 for (i=0;i<=N;i++){    
  scanf( ??? );  
 }

 free(array);  
 return 0;  
}

Что мне нужно ввести в функцию сканирования, чтобы правильно заполнить массив строками? После заполнения я буду использовать что-то вроде strcmp и цикл for, чтобы просканировать массив и найти наиболее часто встречающееся слово? (Я могу сохранить частоты в * freq)


person ManosG    schedule 21.11.2015    source источник


Ответы (3)


Вы хотите выделить массив строк, другими словами, массив указателей на символы, и это именно то, что вы выделяете. Проблема в том, что вы назначаете указатель, возвращаемый calloc, массиву символов.

На самом деле у вас есть два варианта: либо изменить объявление array на указатели "массива" на символ, например char **array, а затем также динамически выделять отдельные строки. Что-то вроде этого

// Allocate an array of pointers
char **array = calloc(N, sizeof(*array));

// Allocate and read all strings
for (size_t i = 0; i < N; ++i)
{
    // Allocate 50 characters
    array[i] = malloc(50);  // No need for `sizeof(char)`, it's always 1

    // Read up to 49 characters (to leave space for the string terminator)
    scanf("%49s", array[i]);
}

Или вы можете изменить тип array, чтобы он был указателем на "строки" фиксированного размера, например

// Define `my_string_type` as an array of 50 characters
typedef char my_string_type[50];

// Declare a pointer to strings, and allocate it
my_string_type *array = calloc(N, sizeof(*array));

// Read all strings from the user
for (size_t i = 0; i < N; ++i)
{
    // Read up to 49 characters (to leave space for the string terminator)
    scanf("%49s", array[i]);
}

Обратите внимание, что я не использую результат calloc или malloc. Никогда не используйте void * в C.

person Some programmer dude    schedule 21.11.2015
comment
А теперь самое интересное: для вопроса о частоте (строка с наибольшим количеством появлений) должен ли я реализовать что-то вроде этого: for (i = 0; i ‹N; ++ i) {for (j = i + 1; j‹ = N; ++ j) {результат = strcmp (array [i], array [j]), если результат = 0 freq [i] = freq [i] + 1}} - person ManosG; 21.11.2015
comment
@ManosG SO Что-то вроде этого могло бы сработать, но будьте осторожны с условием для внутреннего цикла. - person Some programmer dude; 21.11.2015

В функции scanf вам нужно выбрать формат и массив, в который вы хотите передать данные. Например:

scanf("%[^\n]", array); 
person Pete    schedule 21.11.2015

Убедитесь, что введенный размер не превышает заданного вами размера. Попробуйте scanf("%s",array);

person Allen Sun    schedule 21.11.2015
comment
Я только что заметил, что вы просто создаете одномерный массив, но хотите хранить в нем строки? Вам нужно сделать char **, чтобы это сделать. Или это будет просто одна строка с пробелами между некоторыми символами, а не между словами. - person Allen Sun; 21.11.2015