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