九度题目1361:翻转单词顺序

题目1361:翻转单词顺序

题目描述:

JOBDU最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在 本子上。同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思。例如,“student. a am I”。后来才意识到,这家伙原来把句子单词的顺序翻转了,正确的句子应该是“I am a student.”。Cat对一一的翻转这些单词顺序可不在行,你能帮助他么?

输入:

每个测试案例为一行,表示一句英文句子。

我们保证一个句子的单词数不会超过600,每个单词的长度也不会超过30。但是需要注意的是Fish是个不拘小节的人,有时候两个单词中间可能会有很多空格。为了方便起见,你可以认为一行的字符总数不会超过50000个,标点符号可以和普通字母一样处理。

输出:

对应每个测试案例,把翻转后的正确的句子单独输出一行。

样例输入:

student. a am I

I'm a Freshman and I like JOBDU!

样例输出:

I am a student.

JOBDU! like I and Freshman a I'm


自己写的程序:

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

char *revstr(char *str)
{
    char *start = str;
    char *left = str;
    char ch;

    while(*str++)
        ;
    str -=2;

    if(str != NULL)
    {
        while(left < str)
        {
            ch = *left;
            *left++ = *str; //这里是先赋值再++,即先*start = *end,再执行*start++
            *str-- = ch;
        }
    }

    return start;
}

int main(void)
{
    int i = 0, size = 1024, len = 0, n = 0,flag = 0;
    char *str_select = (char *)malloc(size);
    char *buff = (char *)malloc(size);
    char *str_dest = (char *)malloc(size);
    char str_w[100] = {'\0'};
    char *str_src = str_select;
    char *str_set = NULL;
    char *str_wrev = NULL;

    printf("Please input a line of character string: \n");
    fgets(buff, size, stdin); //这里需要注意fgets用法,如果一行能取完,返回的最后两个字符是'\n'和'\0'

    while(*buff != '\n') //由于用了fgets()这里需要判断'\n'
    {
        *str_src++ = *buff++;   //这里有优先级问题*ret_str++等同于*(ret_str++)
    }
    *str_src++ = '\0';

    printf("The src chars is: %s\n", str_select);
    printf("------------------------------------------------------\n");

    str_set = revstr(str_select);

    len = strlen(str_set);
    for(i = 0; i < len; i++)
    {
        if(str_set[i] != ' ')
        {
            str_w[n] = str_set[i];
            n++;
            flag = 1;
        }
        else
        {
            if(flag)
            {
                str_wrev = revstr(str_w);
                printf("%s ", str_wrev);
                flag = 0;
                n = 0;
                memset(str_w, 0, 100);
            }
            else{
                printf(" ");
            }
        }
    }
    str_wrev = revstr(str_w);
    printf("%s", str_wrev);

    return 0;
}

备注:fgets的用法

fgets函数,参数s是缓冲区的首地址,size是缓冲区的长度,该函数从stream所指的文件中读取以'/n'结尾的一行(包括'/n'在内)存到缓冲区s中,并且在该行末尾添加一个'/0'组成完整的字符串。

如果文件中的一行太长,fgets从文件中读了size-1个字符还没有读到'/n',就把已经读到的size-1个字符和一个'/0'字符存入缓冲区,文件中剩下的半行可以在下次调用fgets时继续读。

如果一次fgets调用在读入若干个字符后到达文件末尾,则将已读到的字符串加上'/0'存入缓冲区并返回,如果再次调用fgets则返回NULL,可以据此判断是否读到文件末尾。

注意,对于fgets来说,'/n'是一个特别的字符,而'/0'并无任何特别之处,如果读到'/0'就当作普通字符读入。如果文件中存在'/0'字符(或者说0x00字节),调用fgets之后就无法判断缓冲区中的'/0'究竟是从文件读上来的字符还是由fgets自动添加的结束符,所以fgets只适合读文本文件而不适合读二进制文件,并且文本文件中的所有字符都应该是可见字符,不能有'/0'


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值