Разбить строку на слова - C (СИ)
Формулировка задачи:
здравствуйте, помогите разобраться.
задание: вводится строка произвольной длинны. нужно сформировать несколько новых строк. в каждой строке должно содержаться одно слово.
вот мой код:
у меня это дело работает так:
Я не понимаю откуда мусор берётся в новых строках. ЧЯДНТ?
#include <stdio.h> #include <conio.h> #include <string.h> #include <malloc.h> void clear (char *q){ int i=0; for(; i<strlen(q); ++i) *q='\0'; } char *trim(char *str){ const char *p; char *q; int l; q = malloc(strlen(str)+1); strcpy(q, ""); for (p=str; *(p+=strspn(p, " \t")); p+=l){ l=strcspn(p, " \t"); if (*q) strcat(q, " "); strncat(q, p, l); } q = realloc(q, strlen(q)+1); return q; } char *obtain_data(char *q){ int n=0; char *q1; char *str=malloc(strlen(q)+1); clear(str); printf("Put some text here:\n"); do{ n=scanf("%10[^\n]", q); if (str[0]=='\n') strcpy(str, q); if (str[0]!='\n'){ str=realloc(str, strlen(str)+strlen(q)+1); strcat(str, q); } clear (q); } while (n!=0); str=trim(str); q1=malloc(strlen(str)+1); strcpy(q1, str); free (str); free (q); return q1; } int findword(char *q){ int i=0, k=0; for(; i<strlen(q)+1; ++i){ if (q[i]==' ') break; if (q[i]=='.') break; ++k; } return k; } char* cut (char *r, char *q){ int l=strlen(q), len=0; char *q1; char * f = strchr(q, ' '); len=findword(q); r=realloc(r, len+1); strncpy(r, q, len); q1=malloc(l-len); strncpy(q1, f+1, l-len-1); clear (q); q=realloc(q, l-len); strcpy(q, q1); free (q1); return r; } /*void defrag (char* q){ планируется сделать цикл из cut() }*/ int main() { int k=0; char* c=malloc(101); char *buff=malloc(11); buff=obtain_data(buff); c=cut(c, buff); printf ("%s\n%s\n", c, buff); getch(); }
Решение задачи: «Разбить строку на слова»
textual
Листинг программы
#include <stdio.h> #include <stdlib.h> #include <string.h> #define N 50 //длина буфера для слова //в русском влезет: тысячадевятьсотвосьмидесятидевятимиллиметровый //в английском влезет: Supercalifragilisticexpialidocious //записываем текст в файл посимвольно, попутно считаем длину int lenOfSentence() { int cur = 0; char c; FILE *f = fopen("sentence.txt","w"); if(f == NULL) { printf("Scusi, temporary difficulties finding room for your sentence\n"); getchar(); exit(1); } printf("Put your sentence. Press ENTER' at the end:\n"); do { c = getchar(); if(c!= '\n') fputc(c,f); //убираем ENTER cur++; } while (c!= '\n'); fputc('\0',f); //добавляем символ конца строки fclose(f); return cur; //возвращаем длину текста в файле } //считываем текст из файла в динамическую строку заданной длины char *veryLongString(int len) { char *sentence; FILE *g = fopen("sentence.txt","r"); if(g == NULL) { printf("Scusi, temporary difficulties reading your sentence\n"); getchar(); exit(1); } sentence = (char*) malloc (len); fgets(sentence,len,g); fclose(g); return sentence; } //проверка: является ли символ знаком препинания int inDelimiters(char c) { int i; char delimiters [] = {' ','.',',','-',':',';','!','?'}; for(i=0;i<8;i++) if(c == delimiters[i]) return 1; return 0; } //укоротить текст на слово слева char *cutSentenceByWord(char *sentence, char* word) { int i,cur; cur=strlen(word); while(inDelimiters(sentence[cur])) cur++; char *cut = (char*) malloc (strlen(sentence) - cur); for(i=cur;i<strlen(sentence);i++) cut[i-cur]=sentence[i]; cut[i-cur]= '\0'; return cut; } ////////////////////////////////////////////////////////// int main() { char word [N]; int len = lenOfSentence(); //вводим текст, подсчитываем его длину char *sentence = veryLongString(len); //создаем строку с текстом printf("\nWords:\n"); //разбираем на слова while(strlen(sentence)>0) { sscanf(sentence,"%s",word); //считываем слово как набор символов до пробела if(inDelimiters(word[strlen(word)-1])) //если захватили и знак препинания справа word[strlen(word)-1] = '\0'; //убираем его printf("\t%s\n",word); strcpy(sentence,cutSentenceByWord(sentence,word)); //срезаем текст на найденное //слово слева } flushall(); getchar(); return 0; }
Объяснение кода листинга программы
- Объединение всех строк в одну переменную sentence с помощью функции fgets.
- Проверка на отсутствие знаков препинания с помощью функции inDelimiters.
- Функция cutSentenceByWord для разделения предложения на слова.
- Использование функции sscanf для чтения слова из строки.
- В цикле while происходит чтение слов из строки и их вывод на экран.
- Если последнее символ в слове является знаком препинания, он удаляется.
- После вывода слова, функция cutSentenceByWord используется для удаления этого слова из строки sentence.
- В конце программы используется функция flushall и getchar для очистки буфера ввода.
- Программа возвращает 0, что означает успешное завершение работы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д