Разбить строку на слова - 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;
}

Объяснение кода листинга программы

  1. Объединение всех строк в одну переменную sentence с помощью функции fgets.
  2. Проверка на отсутствие знаков препинания с помощью функции inDelimiters.
  3. Функция cutSentenceByWord для разделения предложения на слова.
  4. Использование функции sscanf для чтения слова из строки.
  5. В цикле while происходит чтение слов из строки и их вывод на экран.
  6. Если последнее символ в слове является знаком препинания, он удаляется.
  7. После вывода слова, функция cutSentenceByWord используется для удаления этого слова из строки sentence.
  8. В конце программы используется функция flushall и getchar для очистки буфера ввода.
  9. Программа возвращает 0, что означает успешное завершение работы.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

8   голосов , оценка 3.875 из 5
Похожие ответы