Show only the last word of a string

Asked

Viewed 2,358 times

0

The purpose of the program is to read a string, ex:

read - Jose Da Silva
print - Silva

I mean, always print the last word of string.

My logic was to read the string back to front, and upon finding the first space stop the loop.

In the example above, running in my program would be:

1 - Read - Jose Da Silva
2 - Kept in a string to assist "Avlis"
3 - Then I create another loop and I read backwards to string auxiliary that would have "Avlis" saved
4 - Backwards would be "Silva"

And at last I show the string helper who will have exactly the last word of string Typed.

Current status of my code:

My code is reading the string backwards and stop at the first (space) he finds. But I don’t know how to create a string help to receive the character of the last word of the first string (reversed), and then reversing this string auxiliary.

NOTE: I am willing to see other logics (which may be easier than mine) to solve this problem.

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

int main (){
    char frase[200];
    int i;

    scanf(" %[^\n]s", frase);

    for (i=strlen(frase)-1;i> -1;i--){
        if (frase[i] == ' '){
            break;
        }

        printf("%c",frase[i]);
    }
    return 0;
 }
  • You have some restraint of what you can use?

  • No, but the interesting thing would be something that does not go far beyond the knowledge of a beginner in programming.

2 answers

5

The simplest, correct and most performative form would be this:

#include <stdio.h>

int main () {
    char frase[200], palavra[200];
    scanf(" %[^\n]s", frase);
    int j = 0;
    for (int i = 0; frase[i] != '\0'; i++) {
        palavra[j] = frase[i];
        j = palavra[j] == ' ' && frase[i + 1] != ' ' && frase[i + 1] != '\0' ? 0 : j + 1;
    }
    palavra[j] = '\0';
    printf("%s", palavra);
}

But if the performance is more important there’s an even better way:

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference. (note the additional blanks at the beginning, middle and end).

I’m considering it may have a single huge word, so I kept the word size equal to the sentence.

When you use the strlen() need to sweep the string all and then sweep again, and this is obviously a bad thing, so I’m stopping the loop when I find the terminator.

It copies character by character from frase for a palavra.

When there is a decision to change the value of the same variable in one way or another if a condition is true or false, it is usually best to use the conditional operator (I think it’s good to learn, because practically it’s just syntax change, the concept of condition you already understand).

The condition has to determine whether to reset the array of the word (j) should be incremented. If not incremented, it should be zeroed, that is, forget everything you were holding and start again in the array of the word. But there are some tricks there.

If it’s a blank space, theoretically it should reset the counter because it starts a new word. But actually the word only starts if the next is a non-white character. So besides being a white the next should be a non-white.

Nor can it have the ending (null character \0), since this would affect the index counter of palavra and we need to know where he is to place the terminator.

If these conditions are not met, additional blanks give wrong result.

We need to put a terminator on array that receives the word, otherwise it potential will have no end and access memory that should not.

Then print the word according to the selected one. But it has a defect because if there is space at the end the space will be printed. You can fix this, but there was nothing in the question that indicated you need.

another failure is to find a tab or other blank character that separates words, or to find a separator symbol, such as punctuation (,, ., ?, etc.), but it may be being used in a way that does not separate words, so everything becomes much more complicated to solve.

But if it is not important to check these cases of additional spaces, then a line solves:

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

int main () {
    char frase[200];
    scanf(" %[^\n]s", frase);
    printf("%s\n", strrchr(frase, ' ') + 1);
}

The function strrchr() just picks up the last block separated by some character.

0


The logic is a little different from the one proposed by you, but it works and (I think it is) simpler (although it reads the whole sentence, through the other method would only read the word itself).

You keep copying every char of the main sentence in another array of char, when finding some space, you "Zera" that array, since having a space we know that is not the last word, at the end of the string it will be with the last word saved, then just finish the array with \0 and print.

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

int main (){
    char frase[200], palavra[50] = "";
    int i, j = 0;

    scanf(" %[^\n]s", frase);

    for(i = 0; frase[i] != '\0'; i++){
        palavra[j] = frase[i]; //usei o contador j em palavra pois ele poderá ser zerado ao encontrar espaço
        if(palavra[j] == ' ') //se encontrar espaço você começa uma nova palavra, mas continua onde parou na frase
            j = 0; 
        else //se não, você incrementa em j
            j++;
    }

    palavra[j] = '\0'; //finaliza o array e depois só imprimir

    printf("%s", palavra);
    fflush(stdin);
    getchar();

    return 0;
}

I fixed the loop like Maniero suggested downstairs, do strlen() the whole loop would actually spend processing while it is different from \0 (as long as it’s not the end of the sentence) it gets better.

  • I thought it was cool, it was simpler.

  • 1

    @Erick, this logic really gets simpler, but I think the other comment would save processing by just reading the last word, as it is a simple algorithm should not make a difference, Anyway if any of the answers answered your question you can accept the answer to help other users (and who answered also kkkk)

  • How do I accept the answer ? I’m not an expert on the site yet.

  • @Erick, has a "V" next to the answer, clicking on it you accept that answer as the correct one, it helps other users to know what the answer and helps who answered

Browser other questions tagged

You are not signed in. Login or sign up in order to post.