Вывести строку с текстового файла так, чтобы слова располагались в алфавитном порядке - C (СИ)
Формулировка задачи:
необходимо вывести строку с текстового файла так, чтобы слова были в алфавитном порядке...реализовал, но не правильно - выводит по алфавиту но не слова, а буквы((не знаю как отделать слова друг от друга и выводить не сплошные буквы, а слова по алфавиту на англ.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare (const void *a, const void *b)
{
return *(char*)a - *(char*)b;
}
int main() {
FILE *f;
char *s;
long int l;
int i;
if ( (f = fopen("func.txt", "r")) == NULL ) exit(0);
fseek(f, 0, SEEK_END);
l = ftell(f) + 1;
fseek(f, 0, SEEK_SET);
s = (char *)malloc(l);
l = fread(s, 1, l, f);
s[l] = '\0';
qsort (s, strlen(s), sizeof(char), compare);
printf("%s\n", s);
fclose(f);
getchar();
}Решение задачи: «Вывести строку с текстового файла так, чтобы слова располагались в алфавитном порядке»
textual
Листинг программы
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXT 100 //максим. число слов
// функция сравнения - для использования в стандартной
// функции qsort
int compare_words( const void *arg1, const void *arg2 )
{
char **s1,**s2;
s1=(char**)arg1;
s2=(char**)arg2;
return strcmp(s1[0],s2[0]);
}
void main( int argc, const char* argv[] )
{
char *words[MAXT]; // массив на 100 указателей под слова
FILE *file;
long size;
char *buffer;
char seps[] = " \t\r\n"; //символы разделители слов
char *token;
int it,i,len;
if(argc != 2) // проверяем был ли передан параметр из командной строки
{
puts("\nUsage: program <FILE.txt>");
return ;
}
file=fopen(argv[1],"r+t"); // Используем переданный параметр как имя файла с текстом для разбора по словам
fseek(file,0,SEEK_END); // устанавливаем текущую позицию в файле в его конец
size=ftell(file); // определяем размер файла
buffer=(char*)malloc(size+1); // выделяем память под чтение всего содержимого файла
fseek(file,0,SEEK_SET); // устанавливаем текущую позицию в файле в его начало
size=fread(buffer,1,size,file); // читаем из фала все его содержимое в буфер
buffer[size]=0; // в последнюю позицию после прочитанного ставим ноль - признак конца строки
fclose(file);// закрываем файл
it=0; // счетчик найденных слов
token = strtok( buffer, seps ); // начинаем обработку буфера по вытаскиванию слов разделенных пробелами
while( token != NULL ) // если очередное слово есть, то продолжаем цикл
{
len=strlen(token);// размер нового слова в символах
if( len > 0 )
{
/*ищем дубликат найденного слова в массиве уже найденных слов*/
i=0;
while( i < it )
{
if( strcmp(words[i],token) == 0 ) break;
i++;
}
if( i == it ) // если дошли до конца массива, то слово в массиве нет и мы его добавляем в массив
{
if(it==MAXT){printf("\nВ массиве нет места под слова"); break;}
/* добавляем в массив найденных слов с проверкой */
words[it]=(char*)malloc(len+1); // выделяем память под хранение нового слова
strcpy(words[it],token); // и копируем его на место хранения в памяти
it++; // увеличиваем счетчик найденных слов
}
}
/* взять следующее слово */
token = strtok( NULL, seps );
}
printf("\n Найдено слов: %d",it);
/*сортируем массив слов в алфавитном порядке*/
qsort(words,it,sizeof(char*),compare_words);// вызов стандартной функции сортировки элементов массива
printf("\nСписок слов");
for(i=0; i < it; i++) printf("\n %s",words[i]); // печатаем список слов в столбик
for(i=0; i < it; i++) free(words[i]); // освобождаем память выделенную для хранения слов
free(buffer);
}
Объяснение кода листинга программы
- Объединение строк с использованием оператора
+может привести к ошибкам при работе с большими объемами данных, так как он работает с ограниченным количеством памяти, что может привести к переполнению буфера. Вместо этого следует использовать функции, специально предназначенные для работы с большими объемами данных, такие как strdup или asprintf. - При использовании функции strcpy следует быть внимательным, так как она копирует строку, начиная с указанного указателя, до первого нулевого символа. Если в исходной строке нет нулевого символа, то при попытке копирования всей строки память под копию будет выделена неправильно.
- Вместо использования функции fread для чтения содержимого файла следует использовать функцию fscanf, которая может обрабатывать символы новой строки.
- При использовании функции malloc следует проверить, что выделение памяти прошло успешно, чтобы избежать ошибок при работе с некорректным указателем.
- При использовании функции strcmp для сравнения строк следует быть внимательным, так как она возвращает значение <0, если первая строка меньше второй, 0, если строки равны, и >0, если первая строка больше второй.
- При использовании функции qsort следует указать, что сравниваются указатели на строки, а не сами строки, чтобы функция работала корректно.
- При использовании функции printf для вывода списка слов следует добавить форматирование, чтобы слова выводились на новой строке.
- При использовании функции free для освобождения памяти следует быть уверенным, что указатель, передаваемый в функцию, является корректным.
- При использовании функции strdup для дублирования строки следует проверить, что выделение памяти прошло успешно, чтобы избежать ошибок при работе с некорректным указателем.
- При использовании функции asprintf следует проверить, что выделение памяти прошло успешно, чтобы избежать ошибок при работе с некорректным указателем.