Разбиение строки на слова - C (СИ)
Формулировка задачи:
Хочу разбить сроку на отдельные слова. Вроде разбивается, но когда вывожу, слова которые меньше или равны 3 символам выводятся хорошо, а вот которые больше с какой-то плохой штукой. Перед тем как использовать буфер чищу, но все равно ничего хорошего не дает.
#include <stdio.h> #include <string.h> #include <conio.h> #include <stdlib.h> #define n 100 struct words { char *wrd; }; words slova[n]; int main() { char string[255],*pos_point; printf("Enter a string "); gets(string); strcat(string," "); int number=0,i,to=0,from=0; for (i=0;i<strlen(string);i++) //Поиск количество пробелов в строке. { if (string[i]==' ') number++; } for (i=0;i<number;i++) { slova[i].wrd = (char*)malloc( sizeof(100) ); memset (slova[i].wrd, 0, sizeof (slova[i].wrd)); pos_point=strchr (string,' '); strncpy (slova[i].wrd,string,pos_point-string); to=pos_point-string; memmove(string + from, string + from + (to+1), strlen(string + from + to) + 1); } for (i=0;i<number;i++) { printf("\n%s %d ",slova[i].wrd,strlen(slova[i].wrd)); } getch(); }
Решение задачи: «Разбиение строки на слова»
textual
Листинг программы
#include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> char *duplicate_string(const char *str) { char *result = malloc(strlen(str) + 1); if(result != NULL) strcpy(result, str); return result; } #define ENSURE(TEST, LABEL, FMT, ...) \ do \ { \ if(!(TEST)) \ { \ fprintf(stderr, "%s:" FMT, \ errno, #__VA_ARGS__); \ goto LABEL; \ } \ } while(0) int main(void) { char buf[BUFSIZ], **words = NULL, *pch; const char *delims = " "; size_t actual_size = 0, actual_limit = 0, rank = 0, i; int ret = EXIT_FAILURE; printf("Enter words separated by spaces: "); fflush(stdout); fgets(buf, BUFSIZ, stdin); ENSURE(buf != NULL, read_err, "%s", "read words"); if((pch = strchr(buf, '\n')) != NULL) *pch = '\0'; for(pch = strtok(buf, delims); pch != NULL; pch = strtok(NULL, delims)) { if(actual_size == actual_limit) { char **temp; temp = realloc(words, (actual_limit = 1 << rank++) * sizeof *words); ENSURE(temp != NULL, words_err, "%s", "allocate memory for words"); words = temp; } words[actual_size] = duplicate_string(pch); ENSURE(words[actual_size] != NULL, words_err, "%s", "allocate memory for a single word"); ++actual_size; } for(i = 0; i < actual_size; ++i) printf("%s\t%d\n", words[i], strlen(words[i])); ret = EXIT_SUCCESS; words_err: for(i = 0; i < actual_size; ++i) free(words[i]); free(words); read_err: exit(ret); }
Объяснение кода листинга программы
- Включаем необходимые заголовочные файлы:
, , , - Создаем функцию duplicate_string, которая выделяет память под строку и копирует в нее исходную строку. Если память не может быть выделена, функция возвращает NULL.
- В функции main() создаем буфер для чтения строки, указатель на слова (массив указателей на строки), указатель на разделитель (пробел), переменные для отслеживания размеров массива слов и строки, а также переменную для отслеживания статуса чтения строки.
- Запрашиваем у пользователя ввод строки, разделяя ее на слова и сохраняя их в массиве words.
- Если во время выделения памяти или чтения строки произошла ошибка, выводим сообщение об ошибке и завершаем работу программы.
- Выводим на экран список слов и их длину.
- Освобождаем память, выделенную под слова, и завершаем работу программы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д