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:
de palavras, número de linhas em branco,
total de linhas,
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:
- Cada chamada de leitura de linha (fgets) conta como 1 linha.
- Linha em branco é aquela que só tem ‘\n’ ou só espaços antes do ‘\n’.
- Letra é todo caractere para o qual isalpha() retorna verdadeiro.
- 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:
- int contaLetras(const char *s): varre a string s e faz isalpha© para cada caractere c; soma 1 quando for letra.
- 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.
- 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.