linux c练习 (纠错总结) 编写一个C函数,将一句话,如”I am from shanghai ”倒置为”shanghai from am I”,即将句子中的单词位置倒置,而不改变单词内部结构

初始代码(错误)

#include<stdio.h>
#include<string.h>
main()
{
	char str[100]={0};       //存放字符串
	char *a[32];              /指针数组,用于存放单词的首地址
	printf("please input a sentence:\n:");
	scanf("%s",str);                //scanf输入字符串遇到'\0'就结束,与输入单个字符不同   《错0》
	int  i=0,j=0,k,count=0;
	
	for(i=0;i<=strlen(str);i++)      《错1》
	{
		if(str[i]<65 && str[i]>90 && str[i]<97 && str[i]>122)    //判断是否为英文单词                  《可修改》
		{
			str[i]='\0';                    //遇到非英文单词的,即空格,赋'\0',这样输出一个单词时从首地址到'\0'停止
			a[j]=str+i-count;          //定位单词首字母首地址
			j++;                               
			count=0                    //记单词长度
		}
		count++;                        《错2》
	}
	
	for(k=j;k>0;k--)             //反顺输出              《错3》
	{
		printf("%s ",a[k]);
	}
	printf("\n");
}

这一题我的大概思路:句子的输入一般是输完一个单词后按下空格输入下一个单词,既然倒置输出,就把每个单词的首字母地址提取出来,在每个单词后面加上’\0’,这样输出时只要提供每个单词的首字母地址,遇到’\0’停止输出,就能把这个单词输出来。只需要把各个首字母地址存放在一个指针数组中,反向输出,就能实现单词位置倒置的功能。

具体做法:i变量是用来for循环的,一直循环到最后的’\0’结束。 count是记单词长度,遇到非字母就清零,重新记下一个单词的长度,a[j]用于存放首字母地址。 k是用于最后反序输出。

以下为需要修改的地方:

  • 错0:scanf用于输入字符串时,遇到’\0’会结束,所以可以选择改用gets(),但是gets函数会无视掉定义的数组长度,有可能会溢出造成错误,在编译时候会警告。这里我们把数组长度设置长一点,暂且避免这一情况。
  • 错1:for(i=0;i<=strlen(str);i++) ,这一行语句,strlen原本目的是为了得出字符串长度确定循环次数。但是我忽略了在for循环里面会不断给每个单词后面的空格赋值为’\0’,而每循环一次,strlen就会再调用一次。strlen的原理是遇到’\0’停止计数,导致得到的循环次数也是会变,造成矛盾。错误很致命。 可以先定义一个指针变量,把数组首地址给它,吧这个指针变量放进for循环语句中。
  • 错2:count++ ,这个语句原本是想用来记单词上次,但是这样写的话,不管是不是英文字母它都会加一。也就是如果if判断是英文字母,它会加一,这没错;但如果判断这不是英文单词,把count清零,它还是会在下面加一,这样单词长度的起点就是1而不是零,导致单词长度计算错误,直接后果就是单词首字母定位错误。错误也很致命。
  • 错3:for(k=j;k>0;k–) 上面的a[j]是从j=0开始接受地址,所以应该是k>=0.
    而k=j这一起始位置也有错,因为在最后一步循环结束时,j++了,所以j值多加了一,在最后输出循环时,j应该把多加了的一减去。不然会出现 在这里插入图片描述,多出的是_libc_start_main,貌似是一个函数,不是很懂是啥。
  • if(str[i]<65 && str[i]>90 && str[i]<97 && str[i]>122) 这一个判断语句我觉得改为 if( str[i] == ’ ’ || !str[i] )会更好一点。

修改后的代码

#include<stdio.h>
#include<string.h>
main()
{
	char str[100]={0};      
	char *a[32];          
	printf("please input a sentence:\n:");
	gets("%s",str);
	int  i=0,j=0,k,count=0;
	
	int len;
	len=strlen(str);
	for(i=0;i<=len;i++)     
	{
		if( str[i] == ' ' || !str[i] )   
		{
			str[i]='\0';                 
			a[j]=str+i-count;         
			j++;                               
			count=0                  
		}
		else
		{
			count++;
		}                     
	}
	
	for(k=j-1;k>=0;k--)        
	{
		printf("%s ",a[k]);
	}
	printf("\n");
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值