O programa a seguir não funciona. Explique detalhadamente qual o problema.
#include <cc50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int
main(void)
{
    printf("Escreva algo: ");
char* s = GetString();
if (s == NULL)
    return 1;
char* w = s;
printf("Capitalizando a cópia...\n");
if (strlen(w) > 0)
    w[0] = toupper(w[0]);
printf("Original: %s\n", s);
printf("Cópia: %s\n", w);
    return 0;
}

Passo 1

Resumo do que o programa faz: ele chama GetString() para ler uma string do usuário, tenta criar uma “cópia” atribuindo
char *w \(=\) s;
e então faz
if (strlen(w) > \(0\))
    w[\(0\)] \(=\) toupper(w[\(0\)]);
para capitalizar a primeira letra de w. Por fim, imprime s e w.

Passo 2

Analisando a linha
char *w \(=\) s;
ela apenas copia o ponteiro: tanto s quanto w passam a apontar para o mesmo buffer em memória. Não há alocação nem duplicação de conteúdo, só um segundo nome para o mesmo bloco de memória.

Passo 3

Quando o código faz
w[\(0\)] \(=\) toupper(w[\(0\)]);
ele está modificando o conteúdo do buffer apontado por w — mas esse buffer é exatamente o de s. Ou seja, não existe “original” e “cópia” independentes: qualquer alteração em w reflete em s porque ambos compartilham o mesmo bloco de memória.

Passo 4

Para criar realmente uma cópia da string, seria necessário alocar memória e copiar o conteúdo, por exemplo:
char *w \(=\) strdup(s);  // em vez de char *w \(=\) s;
ou então usar malloc e strcpy:
char *w \(=\) malloc(strlen(s) \(+1\));
if (w !\(=\) NULL)
    strcpy(w, s);
Assim w e s apontam para buffers distintos, e você pode alterar w[\(0\)] sem afetar s[\(0\)].

Resposta

O problema é que char *w \(=\) s; não faz uma cópia da string, apenas copia o ponteiro. Logo s e w apontam para o mesmo buffer, e modificar um altera o outro.

Exercícios relacionados