Escreva um programa que leia texto do teclado, linha a linha, até chegar ao fim de texto (Ctrl-D ou Ctrl-Z). O programa deverá escrever uma estatística do texto lido: n^circ de palavras, número de linhas em branco, n^circ total de linhas, n^circ de letras. O programa deverá usar funções separadas para cada uma das suas tarefas.

Passo 1

Beleza, o enunciado pede um programa em C que leia texto do teclado até EOF (Ctrl-D no Unix ou Ctrl-Z no Windows) e ao final mostre:
  • Número total de palavras
  • Número de linhas em branco
  • Número total de linhas
  • Número total de letras
Conteúdo: programação em C, manipulação de strings, bibliotecas stdio.h e ctype.h, funções separadas. A teoria que vamos usar:
  1. Cada chamada de leitura de linha (fgets) conta como 1 linha.
  2. Linha em branco é aquela que só tem ‘\n’ ou só espaços antes do ‘\n’.
  3. Letra é todo caractere para o qual isalpha() retorna verdadeiro.
  4. Palavra é sequência de caracteres não-brancos (isgraph ou !isspace) delimitada por espaços ou início/fim de linha.

Passo 2

Planejamento das funções:
  1. int contaLetras(const char *s): varre a string s e faz isalpha© para cada caractere c; soma 1 quando for letra.
  2. int contaPalavras(const char *s): usa uma flag “dentro_palavra”. Sempre que encontrar um caractere não espaco e flag==0, incrementa palavras e seta flag=1. Se encontrar isspace©, seta flag=0.
  3. int linhaEmBranco(const char *s): varre s; se encontrar um caractere que não seja espaço nem ‘\n’, retorna 0; senão retorna 1.

Passo 3

Implementando contaLetras:
#include <ctype.h>
int contaLetras(const char *s) {
    int tot = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (isalpha((unsigned char)s[i])) {
            tot++;
        }
    }
    return tot;
}
Aqui usamos isalpha, que faz parte de <ctype.h>. isalpha© testa se c está entre ‘A’ e ‘Z’ ou ‘a’ e ‘z’.

Passo 4

Implementando contaPalavras:
#include <ctype.h>
int contaPalavras(const char *s) {
    int tot = 0, dentro = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (!isspace((unsigned char)s[i])) {
            if (!dentro) {
                tot++;
                dentro = 1;
            }
        } else {
            dentro = 0;
        }
    }
    return tot;
}
isspace© testa espaços, tab, \n etc. A cada transição “fora de palavra” → “dentro de palavra” contamos 1 palavra.

Passo 5

Implementando linhaEmBranco:
int linhaEmBranco(const char *s) {
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] != ' ' && s[i] != '\t' && s[i] != '\n') {
            return 0; // tem outro caractere
        }
    }
    return 1;
}
Se a string só tiver espaços ou tab ou só ‘\n’, é linha em branco.

Passo 6

Main que junta tudo:
#include <stdio.h>
#include <ctype.h>

// protótipos
int contaLetras(const char *s);
int contaPalavras(const char *s);
int linhaEmBranco(const char *s);

int main(void) {
    char linha[1024];
    int totalLinhas = 0;
    int linhasBranco = 0;
    int totalPalavras = 0;
    int totalLetras = 0;

    // lê cada linha até EOF
    while (fgets(linha, sizeof(linha), stdin) != NULL) {
        totalLinhas++;
        totalLetras   += contaLetras(linha);
        totalPalavras += contaPalavras(linha);
        if (linhaEmBranco(linha)) {
            linhasBranco++;
        }
    }

    // imprime estatísticas
    printf("Linhas totais: %d\n", totalLinhas);
    printf("Linhas em branco: %d\n", linhasBranco);
    printf("Palavras: %d\n", totalPalavras);
    printf("Letras: %d\n", totalLetras);

    return 0;
}

// definições das funções
int contaLetras(const char *s) {
    int tot = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (isalpha((unsigned char)s[i])) tot++;
    }
    return tot;
}

int contaPalavras(const char *s) {
    int tot = 0, dentro = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        if (!isspace((unsigned char)s[i])) {
            if (!dentro) { tot++; dentro = 1; }
        } else {
            dentro = 0;
        }
    }
    return tot;
}

int linhaEmBranco(const char *s) {
    for (int i = 0; s[i] != '\0'; i++) {
        if (s[i] != ' ' && s[i] != '\t' && s[i] != '\n') return 0;
    }
    return 1;
}

Resposta

O código acima resolve o problema, separando as tarefas em funções:
  • contaLetras
  • contaPalavras
  • linhaEmBranco
    e o main cuida de ler, acumular e imprimir os resultados.

Exercícios relacionados