如何在c中拆分字符串中的单词?

如何在c中拆分字符串中的单词?,c,C,我需要建立一个程序,从用户那里接收最多30个字符,然后再使用它。 例如,我需要反转句子,然后打印它,或者旋转它。 我一直试图将句子中的单词一个接一个地复制到[30][31]的矩阵中,但它不起作用。。。有什么想法吗? 我不能用指针。。。 感谢您的帮助: #include <stdio.h> #include <string.h> void main(){ int i=0, j=0, wrongData=0, charC

我需要建立一个程序,从用户那里接收最多30个字符,然后再使用它。 例如,我需要反转句子,然后打印它,或者旋转它。 我一直试图将句子中的单词一个接一个地复制到[30][31]的矩阵中,但它不起作用。。。有什么想法吗? 我不能用指针。。。 感谢您的帮助:

#include <stdio.h>
#include <string.h>
void main(){
    int i=0,
        j=0,
        wrongData=0,
        charCounter=0,
        word=0,
        letter=0;
    char st[100],
         arr[100]={0},
         mat[30][31]={0};

    printf("Please, enter your sentence >");    
    gets(st);

    while(i<strlen(st)){
        if('A'<=st[i] && st[i]<='Z'){
            charCounter++;
            arr[j] = st[i];
            i++;
            j++;
        } else if(st[i]==' '){
            arr[j] = ' ';
            i++;
            j++;
            while(st[i] == ' '){
                i++;
            }
        } else if(st[i]=='\0'){
            arr[j] = '\0';
            break;
        } else {
            puts("ERROR: Incorrect data, try again.");
            wrongData=1;
            break;
        }

        if(wrongData==0){
            if(charCounter>30){
                puts("ERROR: Incorrect data, try again.");
            }
        }
    }

    puts(st);
    puts(arr);
    if(arr[j]==' '){
        word++;
    }

    while(arr[j]!=' ' && letter<32){
        strcpy(mat[word],arr);
    }

    if(arr[j]=='\0'){
        mat[word][letter]=arr[j];
    }       

    puts(mat[word]);
}

考虑到你的评论

问题是我需要颠倒单词而不是字母。。。对于 如果字符串是“猫讨厌狗”,我需要在末尾 狗讨厌猫

那么我想你的意思是

#include <stdio.h>
#include <ctype.h>
#include <string.h>

char * reverse_words( char s[] )
{
    for ( char *p = s, *q = s; *p; p = q )
    {
        while ( isspace( ( unsigned char )*p ) ) ++p;

        q = p;

        while ( *q && !isspace( ( unsigned char )*q ) ) ++q;

        for ( size_t i = 0; i < ( q - p ) / 2; i++ )
        {
            char c = p[i];
            p[i] = q[-i-1];
            q[-i-1] = c;
        }
    }

    for ( size_t i = 0, n = strlen( s ); i < n / 2; i++ )
    {
        char c = s[i];
        s[i] = s[n-i-1];
        s[n-i-1] = c;
    }

    return s;
}

int main( void ) 
{
    char s[] = "cats hates dogs";

    puts( s );
    puts( reverse_words( s ) );

    return 0;
}

这是另一种方法。其思想是遍历字符串并记录每个单词开始和结束的索引。然后,可以按相反的顺序打印文字。顺便说一句,它也将很容易旋转的话

#include<stdio.h>
#include <string.h>

int main() {
  char st[100] = "here we go again";
  int start[30] = { 0 };
  int end[30] = { 0 };
  int count = 0;
  int len = strlen(st);
  int i, j;


  // Find start and end index of each word
  start[0] = 0;
  for(i = 0; i < len; ++i)
  {
    if (st[i] == ' ')
    {
      end[count] = i;
      ++count;
      start[count] = i + 1;
    }
  }
  end[count] = len;

  // Print the words in reverse order
  for(i=count; i >= 0; --i)
  {
    for (j = start[i]; j < end[i]; ++j)
    {
      printf("%c", st[j]);
    }
    printf(" ");
  }
  printf("\n");

  return 0;
}
输出:

我们再来一次


按照以下方式修复您的方法:

#include <stdio.h>
//#include <string.h>

#define MAX_LEN 30

int main(void){
    int i, j, n, word;
    char st[100], arr[100], mat[MAX_LEN / 2][MAX_LEN + 1];

    printf("Please, enter your sentence (up to %d chars and A-Z or space)\n>", MAX_LEN);fflush(stdout);
    scanf("%99[^\n]%*c", st);

    //validate and reduce of spaces
    for(j = i = 0; st[i]; ++i){
        if(i > MAX_LEN){
            fputs("ERROR: Incorrect data, try again.\n", stderr);
            return 1;
        }
        if('A'<=st[i] && st[i]<='Z'){
            arr[j++] = st[i];
        } else if(st[i]==' '){
            arr[j++] = ' ';
            while(st[++i] == ' ')//Skip a continuous space
                ;
            --i;//one back for next loop
        } else {
            fputs("ERROR: Incorrect data, try again.\n", stderr);
            return 1;
        }
    }
    arr[j] = '\0';//st[i]=='\0' never become true in loop

#if DEBUG
    puts(st);
    puts(arr);
#endif

    //split to word
    for(word = j = i = 0; arr[i];){
        while(arr[i] == ' ')
            ++i;//skip space
        while(arr[i] != ' ' && arr[i] != '\0')
            mat[word][j++] = arr[i++];
        mat[word++][j] = '\0';
        j = 0;
    }
#if DEBUG
    for(i = 0; i < word; ++i)
        puts(mat[i]);
#endif
    puts("reverse word");
    for(i = 0; i < word; ++i){
        if(i)
            putchar(' ');
        printf("%s", mat[word-1-i]);
    }
    puts("\nrotate word");
    printf("Please, enter number of rotate\n>");fflush(stdout);
    scanf("%d", &n);
    for(i = 0; i < word; ++i){
        if(i)
            putchar(' ');
        printf("%s", mat[(i+n)%word]);//rotate left
    }
}

你说它不起作用是什么意思?哪种方式?它不打印我从矩阵中要求的内容。。。好像我没有像我想的那样将arr输入矩阵。或者我的打印代码不正确……您需要学习如何表达您的意思并清楚地描述需求。下面,您已经开始解释“反向”的含义,但尚未开始解释“旋转”的含义。如果你不能解释清楚,那么你就很难帮助你。如果你把一句话倒转过来,那你就太复杂了。只需向后遍历字符串,并在找到空格“”字符时做出反应。除了空格以外的任何东西都是单词的一部分。从右到左抓取单词,将它们放在数组前面并添加空格,然后打印出来。@ron ramon不清楚你说的“玩它”是什么意思。例如,我需要反转句子,然后打印它,或者旋转它,这意味着我需要从用户那里获取字符串,然后反转句子字符串中的单词,这样第一个单词将与最后一个单词切换,第二个单词与最后一个单词之前的单词切换,依此类推。或者在其他选项中,将N个单词从句子的开头移到结尾。例如,如果一句话是“世界正在失去理智”,而用户想要移动3个单词,那么新的句子将失去理智world@ronramon我显示的函数不使用strtok。至于isspace函数,你可以用它代替空格和制表符的直接比较。它非常有用,谢谢。如果我需要先反转它,然后再打印它,继续填充它?我该怎么做?@ronramon你的意思是像那样反转后旋转?您将能够实际交换,而不仅仅是通过索引。您给我的是无价的,但我需要反转然后打印,而不是打印反转…因此,数组中的位置可以通过交换来更改。是的。非常好。这就是为什么我不想把这些单词拼凑出来,放到矩阵中,然后从那里打印出来。因为以后我将不得不接受相反的单词并继续填充它们。。。
#include <stdio.h>
//#include <string.h>

#define MAX_LEN 30

int main(void){
    int i, j, n, word;
    char st[100], arr[100], mat[MAX_LEN / 2][MAX_LEN + 1];

    printf("Please, enter your sentence (up to %d chars and A-Z or space)\n>", MAX_LEN);fflush(stdout);
    scanf("%99[^\n]%*c", st);

    //validate and reduce of spaces
    for(j = i = 0; st[i]; ++i){
        if(i > MAX_LEN){
            fputs("ERROR: Incorrect data, try again.\n", stderr);
            return 1;
        }
        if('A'<=st[i] && st[i]<='Z'){
            arr[j++] = st[i];
        } else if(st[i]==' '){
            arr[j++] = ' ';
            while(st[++i] == ' ')//Skip a continuous space
                ;
            --i;//one back for next loop
        } else {
            fputs("ERROR: Incorrect data, try again.\n", stderr);
            return 1;
        }
    }
    arr[j] = '\0';//st[i]=='\0' never become true in loop

#if DEBUG
    puts(st);
    puts(arr);
#endif

    //split to word
    for(word = j = i = 0; arr[i];){
        while(arr[i] == ' ')
            ++i;//skip space
        while(arr[i] != ' ' && arr[i] != '\0')
            mat[word][j++] = arr[i++];
        mat[word++][j] = '\0';
        j = 0;
    }
#if DEBUG
    for(i = 0; i < word; ++i)
        puts(mat[i]);
#endif
    puts("reverse word");
    for(i = 0; i < word; ++i){
        if(i)
            putchar(' ');
        printf("%s", mat[word-1-i]);
    }
    puts("\nrotate word");
    printf("Please, enter number of rotate\n>");fflush(stdout);
    scanf("%d", &n);
    for(i = 0; i < word; ++i){
        if(i)
            putchar(' ');
        printf("%s", mat[(i+n)%word]);//rotate left
    }
}