Exercícios de Programação C: Soluções e Desafios (Conjuntos 76-80)

Este documento apresenta uma série de exercícios de programação em C, abrangendo diferentes aspectos da linguagem, desde manipulação de strings e arrays até operações com arquivos e cálculo de séries. Cada conjunto de exercícios inclui um problema de preenchimento de código, um de modificação de código e um de design de função, todos com foco na lógica e na correção.

Conjunto 76

1. Preenchimento de Código

Na função fornecida, o objetivo é encontrar todos os números inteiros entre 100 e 999 (inclusive) cuja soma dos dígitos seja igual a um valor específico somaAlvo (um inteiro positivo). A função deve imprimir esses números e retornar a contagem de quantos números atendem à condição.

Por exemplo, se somaAlvo for 5, os números entre 100 e 999 com soma de dígitos igual a 5 são: 104, 113, 122, 131, 140, 203, 212, 230, 302, 311, 320, 401, 410, 500. Existem 15 números no total.

Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.

#include <stdio.h>

int encontrarNumerosComSomaDeDigitos(int somaAlvo)
{
    int numeroAtual, digitoUnidade, digitoDezena, digitoCentena;
    int contador = 0;
    numeroAtual = 100;
    
    // Lacuna 1
    while (numeroAtual <= ___1___)
    {
        digitoUnidade = numeroAtual % 10;
        // Lacuna 2
        digitoDezena = (___2___ / 10) % 10;
        digitoCentena = numeroAtual / 100;
        
        // Lacuna 3
        if (digitoUnidade + digitoDezena + digitoCentena == ___3___)
        {
            printf("%d ", numeroAtual);
            contador++;
        }
        numeroAtual++;
    }
    return contador;
}

int main()
{
    int valorUsuario = -1;
    while (valorUsuario < 0)
    {
        printf("Por favor, insira um valor (soma > 0): ");
        scanf("%d", &valorUsuario);
    }
    printf("\nO resultado e: %d\n", encontrarNumerosComSomaDeDigitos(valorUsuario));
    return 0;
}

2. Modificação de Código

A função processarNumeros tem como objetivo selecionar números entre 10 e 55 que são divisíveis por 3 e contêm o dígito 5 em qualquer uma de suas posições. Esses números devem ser armazenados em um array apontado por arraySaida, e a função deve retornar a quantidade de números encontrados.

Corrija os erros nas partes indicadas da função processarNumeros para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do programa.

#include <stdio.h>

int processarNumeros(int *arraySaida)
{
    int numero, digitoUnidade, digitoDezena;
    int indice = 0;
    for (numero = 10; numero <= 55; numero++)
    {
        // ERRO 1
        digitoDezena = numero % 10;
        digitoUnidade = numero - digitoDezena * 10;
        
        if ((numero % 3 == 0 && digitoDezena == 5) || (numero % 3 == 0 && digitoUnidade == 5))
        {
            arraySaida[indice] = numero;
            indice++;
        }
    }
    // ERRO 2
    return numero;
}

int main()
{
    int meuArray[100], k, quantidade;
    quantidade = processarNumeros(meuArray);
    printf("Os numeros encontrados sao:\n");
    for (k = 0; k < quantidade; k++)
        printf("%4d", meuArray[k]);
    printf("\n");
    return 0;
}

3. Design de Função

Assumindo que uma string de entrada contém apenas letras e asteriscos (\*), crie a função removerAsteriscosFinais. Sua funcionalidade é remover todos os asteriscos que aparecem no final da string. Os asterisocs localizados no início ou no meio da string não devem ser removidos.

Por exemplo, se a string for "\*****A\*BC\*DEF\*G\***", após a remoção, o conteúdo da string deverá ser "\*****A\*BC\*DEF\*G".

Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função removerAsteriscosFinais.

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

void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar

void removerAsteriscosFinais(char *texto)
{
    // SEU CÓDIGO AQUI
}

int main()
{
    char textoEntrada[81];
    printf("Digite uma string:\n");
    fgets(textoEntrada, sizeof(textoEntrada), stdin); // Usar fgets para entrada segura
    textoEntrada[strcspn(textoEntrada, "\n")] = 0; // Remover newline, se houver
    
    removerAsteriscosFinais(textoEntrada);
    
    printf("A string apos remocao e:\n");
    puts(textoEntrada);
    
    funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
    return 0;
}

void funcaoAuxiliarNaoModificar(void)
{
    /* Esta função é usada para abrir arquivos, inserir dados, chamar a função, exibir dados e fechar arquivos. */
    FILE *entradaArquivo, *saidaArquivo;
    int i;
    char buffer[81];
    
    entradaArquivo = fopen("entrada.dat", "r");
    saidaArquivo = fopen("saida.dat", "w");
    
    if (!entradaArquivo || !saidaArquivo) {
        perror("Erro ao abrir arquivos");
        return;
    }
    
    for (i = 0; i < 10; i++)
    {
        if (fscanf(entradaArquivo, "%s", buffer) != 1) break;
        removerAsteriscosFinais(buffer);
        fprintf(saidaArquivo, "%s\n", buffer);
    }
    fclose(entradaArquivo);
    fclose(saidaArquivo);
}

Soluções para o Conjunto 76

1. Preenchimento de Código:

    while (numeroAtual <= 999) // ___1___
    {
        // ...
        digitoDezena = (numeroAtual / 10) % 10; // ___2___
        // ...
        if (digitoUnidade + digitoDezena + digitoCentena == somaAlvo) // ___3___
        // ...

2. Modificação de Código:

    digitoUnidade = numero % 10; // ERRO 1 Corrigido
    digitoDezena = numero / 10;  // ERRO 1 Corrigido
    // ...
    return indice; // ERRO 2 Corrigido

3. Design de Função:

void removerAsteriscosFinais(char *texto)
{
    int tamanho = strlen(texto);
    if (tamanho == 0) return;

    int indiceFinal = tamanho - 1;
    while (indiceFinal >= 0 && texto[indiceFinal] == '*')
    {
        indiceFinal--;
    }
    // O próximo caractere após 'indiceFinal' deve ser o terminador nulo
    texto[indiceFinal + 1] = '\0';
}

Conjunto 77

1. Preenchimento de Código

A função calcularSerie é responsável por computar a soma de uma série até que o valor absoluto do termo atual seja menor ou igual a um limite limiteErro (10-3 no exemplo). O resultado da soma é retornado como o valor da função.

Por exemplo, se o valor do parâmetro limiteErro for 1e-3, o valor retornado da função é 2.985678.

Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.

#include <stdio.h>
#include <math.h> // Para usar fabs

double calcularSerie(double limiteErro)
{
    int contadorTermo;
    double somaTotal, valorTermo;
    
    // Lacuna 1
    somaTotal = 0;
    contadorTermo = ___1___;
    valorTermo = 1.0;
    
    while (fabs(valorTermo) > limiteErro) // Usando fabs para valor absoluto
    {
        // Lacuna 2
        ___2___;
        // Lacuna 3
        valorTermo = (2.0 * contadorTermo - 1) / ((___3___) * (2.0 * contadorTermo));
        somaTotal += valorTermo;
    }
    return somaTotal;
}

int main()
{
    double e = 1e-3;
    printf("\nO resultado e: %f\n", calcularSerie(e));
    return 0;
}

2. Modificação de Código

A função unirStringReversa é projetada para concatenar uma string (apontada por stringOriginal) com sua versão invertida, armazenando o novo resultado em um array apontado por stringConcatenada.

Por exemplo, se stringOriginal for "ABCD", o conteúdo de stringConcatenada deverá ser "ABCDDCBA".

Corrija os erros nas partes indicadas da função unirStringReversa para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do programa.

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

// ERRO 1
void unirStringReversa(char stringOriginal, char stringConcatenada)
{
    int i, comprimento;
    comprimento = strlen(stringOriginal);
    
    for (i = 0; i < comprimento; i++)
        stringConcatenada[i] = stringOriginal[i];
    
    for (i = 0; i < comprimento; i++)
        stringConcatenada[comprimento + i] = stringOriginal[comprimento - 1 - i];
    
    // ERRO 2
    stringConcatenada[2 * comprimento - 1] = '\0';
}

int main()
{
    char s[100], t[100];
    printf("\nPor favor, digite a string S: ");
    scanf("%s", s);
    
    unirStringReversa(s, t);
    
    printf("\nO resultado e: %s\n", t);
    return 0;
}

3. Design de Função

Implemente a função filtrarCaracteres. Sua tarefa é remover da string apontada por stringFonte todos os caracteres, exceto aqueles cujo índice na string é ímpar E cujo valor ASCII também é ímpar. Os caracteres restantes devem formar uma nova string, armazenada no array apontado por stringDestino.

Por exemplo, se o conteúdo de stringFonte for "ABCDEFG12345", o conteúdo de stringDestino deverá ser "135".

Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função filtrarCaracteres.

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

void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar

void filtrarCaracteres(char *stringFonte, char stringDestino[])
{
    // SEU CÓDIGO AQUI
}

int main()
{
    char s[100], t[100];
    printf("\nPor favor, digite a string S: ");
    scanf("%s", s);
    
    filtrarCaracteres(s, t);
    
    printf("\nO resultado e: %s\n", t);
    
    funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
    return 0;
}

void funcaoAuxiliarNaoModificar(void)
{
    /* Esta função é usada para abrir arquivos, inserir dados, chamar a função, exibir dados e fechar arquivos. */
    char s[100], t[100];
    FILE *leituraArquivo, *escritaArquivo;
    int i;
    
    leituraArquivo = fopen("entrada.dat", "r");
    escritaArquivo = fopen("saida.dat", "w");
    
    if (!leituraArquivo || !escritaArquivo) {
        perror("Erro ao abrir arquivos");
        return;
    }
    
    for (i = 0; i < 10; i++)
    {
        if (fscanf(leituraArquivo, "%s", s) != 1) break;
        filtrarCaracteres(s, t);
        fprintf(escritaArquivo, "%s\n", t);
    }
    fclose(leituraArquivo);
    fclose(escritaArquivo);
}

Soluções para o Conjunto 77

1. Preenchimento de Código:

    contadorTermo = 0; // ___1___
    // ...
    contadorTermo++; // ___2___
    // ...
    valorTermo = (2.0 * contadorTermo - 1) / ((2.0 * contadorTermo) * (2.0 * contadorTermo)); // ___3___
    // ...

2. Modificação de Código:

void unirStringReversa(char *stringOriginal, char *stringConcatenada) // ERRO 1 Corrigido
{
    // ...
    stringConcatenada[2 * comprimento] = '\0'; // ERRO 2 Corrigido
}

3. Design de Função:

void filtrarCaracteres(char *stringFonte, char stringDestino[])
{
    int i, j = 0;
    for (i = 0; stringFonte[i] != '\0'; i++)
    {
        // Verifica se o índice é ímpar E o valor ASCII é ímpar
        if ((i % 2 != 0) && (stringFonte[i] % 2 != 0))
        {
            stringDestino[j++] = stringFonte[i];
        }
    }
    stringDestino[j] = '\0'; // Termina a nova string
}

Conjunto 78

1. Preenchimento de Código

A função inverterArray tem a finalidade de inverter os valores dos elementos em um array.

Por exemplo, se os dados no array apontado por arr forem sequencialmente: 1, 2, 3, 4, 5, 6, 7, 8, 9, após a inversão eles deverão ser: 9, 8, 7, 6, 5, 4, 3, 2, 1.

Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.

#include <stdio.h>

void inverterArray(int arr[], int tamanho)
{
    int i, temp;
    // Lacuna 1
    for (i = 0; i < ___1___; i++)
    {
        temp = arr[i];
        // Lacuna 2
        arr[i] = arr[tamanho - 1 - ___2___];
        // Lacuna 3
        ___3___ = temp;
    }
}

int main()
{
    int dados[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}, i;
    printf("\nDados originais:\n");
    for (i = 0; i < 9; i++)
        printf("%4d ", dados[i]);
    printf("\n");
    
    inverterArray(dados, 9);
    
    printf("\nDados apos inversao:\n");
    for (i = 0; i < 9; i++)
        printf("%4d ", dados[i]);
    printf("\n");
    return 0;
}

2. Modificação de Código

A função produtoDosDigitos tem a funcionalidade de calcular o produto dos dígitos de um número inteiro valor.

Por exemplo, se a entrada for 252, a saída deverá ser 20; se a entrada for 202, a saída deverá ser 0.

Corrija os erros nas partes indicadas da função produtoDosDigitos para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do prograam.

#include <stdio.h>

long produtoDosDigitos(long valor)
{
    // ERRO 1
    long resultadoProduto;
    do
    {
        resultadoProduto *= valor % 10;
        // ERRO 2
        valor = 10;
    } while (valor);
    return (resultadoProduto);
}

int main()
{
    long n;
    printf("Por favor, digite um numero: ");
    scanf("%ld", &n);
    printf("\n%ld\n", produtoDosDigitos(n));
    return 0;
}

3. Design de Função

Desenvolva a função encontrarMaximoEIndice. Sua finalidade é encontrar o maior valor em um array unidimensional e seu respectivo índice. O maior valor e o índice são retornados através dos parâmetros de ponteiro maximo e indiceMaximo, respectivamente.

Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função encontrarMaximoEIndice.

#include <stdio.h>
#include <stdlib.h> // Para rand()

void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar

void encontrarMaximoEIndice(int arr[], int tamanho, int *maximo, int *indiceMaximo)
{
    // SEU CÓDIGO AQUI
}

int main()
{
    int i, valores[20], maiorValor, indiceDoMaior, N = 10;
    for (i = 0; i < N; i++)
    {
        valores[i] = rand() % 50;
        printf("%4d", valores[i]);
    }
    printf("\n");
    
    encontrarMaximoEIndice(valores, N, &maiorValor, &indiceDoMaior);
    
    printf("Max =%5d , Indice =%4d\n", maiorValor, indiceDoMaior);
    
    funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
    return 0;
}

void funcaoAuxiliarNaoModificar(void)
{
    /* Esta função é usada para abrir arquivos, inserir dados, chamar a função, exibir dados e fechar arquivos. */
    FILE *arquivoLeitura, *arquivoEscrita;
    int i, x[20], max, index, n = 10, j;
    
    arquivoLeitura = fopen("entrada.dat", "r");
    arquivoEscrita = fopen("saida.dat", "w");
    
    if (!arquivoLeitura || !arquivoEscrita) {
        perror("Erro ao abrir arquivos");
        return;
    }
    
    for (i = 0; i < 10; i++)
    {
        for (j = 0; j < n; j++)
            if (fscanf(arquivoLeitura, "%d,", &x[j]) != 1) break;
        
        encontrarMaximoEIndice(x, n, &max, &index);
        fprintf(arquivoEscrita, "Max=%d,Indice=%d\n", max, index);
    }
    fclose(arquivoLeitura);
    fclose(arquivoEscrita);
}

Soluções para o Conjunto 78

1. Preenchimento de Código:

    for (i = 0; i < tamanho / 2; i++) // ___1___
    {
        temp = arr[i];
        arr[i] = arr[tamanho - 1 - i]; // ___2___
        arr[tamanho - 1 - i] = temp; // ___3___
    }

2. Modificação de Código:

long produtoDosDigitos(long valor)
{
    long resultadoProduto = 1; // ERRO 1 Corrigido: Inicializar com 1 para produto
    do
    {
        resultadoProduto *= valor % 10;
        valor /= 10; // ERRO 2 Corrigido: Dividir por 10 para remover o último dígito
    } while (valor);
    return (resultadoProduto);
}

3. Design de Função:

void encontrarMaximoEIndice(int arr[], int tamanho, int *maximo, int *indiceMaximo)
{
    int i;
    // Assume que o array não está vazio e inicializa com o primeiro elemento
    *maximo = arr[0];
    *indiceMaximo = 0;

    for (i = 1; i < tamanho; i++)
    {
        if (arr[i] > *maximo)
        {
            *maximo = arr[i];
            *indiceMaximo = i;
        }
    }
}

Conjunto 79

1. Preenchimento de Código

A função analisarNumeros calcula a média de NUM_ELEMENTOS números (todos positivos) em um array apontado por dados. A média é retornada à função principal através do parâmetro de ponteiro mediaCalculada. Além disso, a função retorna como seu valor o número que é menor que a média e o mais próximo dela.

Por exemplo, para 10 números positivos: 40 30 32 40 6 17 45 15 48 26, a média é: 35.500000. O valor retornado pela função principal deve ser 30.0.

Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.

#include <stdio.h>
#include <stdlib.h> // Para rand()
#define NUM_ELEMENTOS 10

double analisarNumeros(double dados[], double *mediaCalculada)
{
    int i, indiceProximo = 0;
    double diferencaMinima = 32767.0; // Um valor grande inicial para a menor diferença
    double soma = 0;
    
    for (i = 0; i < NUM_ELEMENTOS; i++)
        soma += dados[i];
    
    // Lacuna 1
    ___1___ = soma / NUM_ELEMENTOS;
    
    for (i = 0; i < NUM_ELEMENTOS; i++)
        if (dados[i] < *mediaCalculada && (*mediaCalculada - dados[i]) <= diferencaMinima)
        {
            // Lacuna 2
            diferencaMinima = *mediaCalculada - dados[i];
            indiceProximo = ___2___;
        }
    // Lacuna 3
    return ___3___;
}

int main()
{
    int i;
    double valores[NUM_ELEMENTOS], media, numeroProximo;
    
    for (i = 0; i < NUM_ELEMENTOS; i++)
    {
        valores[i] = rand() % 50 + 1; // Gerar números positivos
        printf("%4.0f ", valores[i]);
    }
    printf("\n");
    
    numeroProximo = analisarNumeros(valores, &media);
    
    printf("\nA media e: %f\n", media);
    printf("O numero mais proximo e: %5.1f\n", numeroProximo);
    printf("\n");
    return 0;
}

2. Modificação de Código

A função calcularSerieSubtrativa tem a finalidade de calcular o valor de S, onde S é uma série do tipo aa..aa - ...aaa - aa - a (onde aa..aa representa n repetições do dígito a, e os valores de a e n estão entre 1 e 9).

Por exemplo, se a=3 e n=6, a expressão é: S = 333333 - 33333 - 3333 - 333 - 33 - 3, cujo valor é 296298.

Corrija os erros nas partes indicadas da função calcularSerieSubtrativa para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do programa.

#include <stdio.h>

long calcularSerieSubtrativa(int digito, int repeticoes)
{
    int j;
    // ERRO 1
    long somaSerie = 0, termoAtual = 1;
    
    for (j = 0; j < repeticoes; j++)
        termoAtual = termoAtual * 10 + digito; // Constrói o maior número a...a
    
    somaSerie = termoAtual; // Inicializa a soma com o maior número
    
    for (j = 1; j < repeticoes; j++)
    {
        // ERRO 2
        termoAtual = termoAtual % 10; // Reduz o termo atual para o próximo na série
        somaSerie = somaSerie - termoAtual;
    }
    return (somaSerie);
}

int main()
{
    int a, n;
    printf("\nPor favor, digite 'a' e 'n': ");
    scanf("%d%d", &a, &n);
    printf("O valor da funcao e: %ld\n", calcularSerieSubtrativa(a, n));
    return 0;
}

3. Design de Função

Crie a função contarFrequenciaLetras. Sua função é contar quantas vezes cada uma das 26 letras minúsculas ('a' a 'z') aparece na string textoEntrada e armazenar essas contagens no array apontado por frequencias.

Por exemplo, se a string de entrada for: "abcdefgabcdeabc", a saída do programa deverá ser: 3 3 3 2 2 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 (representando as contagens de 'a' a 'z').

Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função contarFrequenciaLetras.

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

void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar

void contarFrequenciaLetras(char *textoEntrada, int frequencias[])
{
    // SEU CÓDIGO AQUI
}

int main()
{
    char texto[1000];
    int contagens[26], k;
    
    printf("\nPor favor, digite uma string de caracteres: ");
    scanf("%s", texto);
    
    contarFrequenciaLetras(texto, contagens);
    
    for (k = 0; k < 26; k++)
        printf("%d ", contagens[k]);
    printf("\n");
    
    funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
    return 0;
}

void funcaoAuxiliarNaoModificar(void)
{
    /* Esta função é usada para abrir arquivos, inserir dados de teste, chamar a função fun e exibir/gravar dados. */
    char texto[1000];
    int contagens[26], k, i;
    FILE *leituraArquivo, *escritaArquivo;
    
    leituraArquivo = fopen("entrada.dat", "r");
    escritaArquivo = fopen("saida.dat", "w");
    
    if (!leituraArquivo || !escritaArquivo) {
        perror("Erro ao abrir arquivos");
        return;
    }
    
    for (i = 0; i < 10; i++)
    {
        if (fscanf(leituraArquivo, "%s", texto) != 1) break;
        contarFrequenciaLetras(texto, contagens);
        for (k = 0; k < 26; k++)
            fprintf(escritaArquivo, "%d ", contagens[k]);
        fprintf(escritaArquivo, "\n");
    }
    fclose(leituraArquivo);
    fclose(escritaArquivo);
}

Soluções para o Conjunto 79

1. Preenchimento de Código:

    *mediaCalculada = soma / NUM_ELEMENTOS; // ___1___
    // ...
    indiceProximo = i; // ___2___
    // ...
    return dados[indiceProximo]; // ___3___

2. Modificação de Código:

long calcularSerieSubtrativa(int digito, int repeticoes)
{
    int j;
    long somaSerie = 0, termoAtual = 0; // ERRO 1 Corrigido: Inicializar termoAtual com 0
    
    for (j = 0; j < repeticoes; j++)
        termoAtual = termoAtual * 10 + digito;
    
    somaSerie = termoAtual;
    
    for (j = 1; j < repeticoes; j++)
    {
        termoAtual = termoAtual / 10; // ERRO 2 Corrigido: Dividir por 10 para remover o último dígito
        somaSerie = somaSerie - termoAtual;
    }
    return (somaSerie);
}

3. Design de Função:

void contarFrequenciaLetras(char *textoEntrada, int frequencias[])
{
    int i;
    // Inicializa todas as contagens para zero
    for (i = 0; i < 26; i++)
    {
        frequencias[i] = 0;
    }

    // Percorre a string e conta as frequências
    for (i = 0; textoEntrada[i] != '\0'; i++)
    {
        if (textoEntrada[i] >= 'a' && textoEntrada[i] <= 'z')
        {
            frequencias[textoEntrada[i] - 'a']++;
        }
    }
}

Conjunto 80

1. Preenchimento de Código

O programa define uma estrutura Aluno para armazenar número de matrícula, nome e notas de 3 disciplinas. Todos os dados dos alunos são escritos em modo binário no arquivo "student.dat". A função atualizarNotasAluno busca os dados de um aluno específico pelo número de matrícula no arquivo. Se encontrado, lê os dados, aumenta cada nota em 3 pontos e reescreve os dados modificados no mesmo local do arquivo, mantendo os outros dados inalterados. Se o aluno não for encnotrado, nenhuma ação é realizada.

Preencha as lacunas no código abaixo para que ele produza o resultado correto. Não adicione nem remova linhas, e não altere a estrutura do programa.

#include <stdio.h>
#define NUM_ALUNOS 5

typedef struct aluno
{
    long matricula;
    char nome[10];
    float notas[3];
} Aluno;

void atualizarNotasAluno(char *nomeArquivo, long matriculaAlvo)
{
    FILE *fp;
    Aluno alunoLido;
    int i;
    
    fp = fopen(nomeArquivo, "rb+");
    if (fp == NULL) {
        perror("Erro ao abrir o arquivo");
        return;
    }
    
    // Lacuna 1
    while (!___1___(fp))
    {
        fread(&alunoLido, sizeof(Aluno), 1, fp);
        // Lacuna 2
        if (alunoLido.matricula ___2___ matriculaAlvo)
            break;
    }
    
    if (!feof(fp)) // Se o aluno foi encontrado e o final do arquivo não foi atingido
    {
        for (i = 0; i < 3; i++)
            alunoLido.notas[i] += 3;
        
        // Lacuna 3: Voltar o ponteiro para o início do registro lido
        fseek(fp, -1L * ___3___, SEEK_CUR);
        fwrite(&alunoLido, sizeof(Aluno), 1, fp);
    }
    fclose(fp);
}

int main()
{
    Aluno listaAlunos[NUM_ALUNOS] = {{10001, "MaChao", 91, 92, 77},
                                     {10002, "CaoKai", 75, 60, 88},
                                     {10003, "LiSi", 85, 70, 78},
                                     {10004, "FangFang", 90, 82, 87},
                                     {10005, "ZhangSan", 95, 80, 88}},
          alunosLidos[NUM_ALUNOS];
    int i, j;
    FILE *fp;
    
    fp = fopen("student.dat", "wb");
    if (fp == NULL) { perror("Erro ao criar student.dat"); return 1; }
    fwrite(listaAlunos, sizeof(Aluno), NUM_ALUNOS, fp);
    fclose(fp);
    
    printf("\nDados originais:\n");
    fp = fopen("student.dat", "rb");
    if (fp == NULL) { perror("Erro ao abrir student.dat"); return 1; }
    fread(alunosLidos, sizeof(Aluno), NUM_ALUNOS, fp);
    fclose(fp);
    
    for (j = 0; j < NUM_ALUNOS; j++)
    {
        printf("\nMatricula: %ld  Nome: %-8s      Notas:  ", alunosLidos[j].matricula, alunosLidos[j].nome);
        for (i = 0; i < 3; i++)
            printf("%6.2f ", alunosLidos[j].notas[i]);
        printf("\n");
    }
    
    atualizarNotasAluno("student.dat", 10003); // Modificar notas do aluno 10003
    
    fp = fopen("student.dat", "rb");
    if (fp == NULL) { perror("Erro ao reabrir student.dat"); return 1; }
    fread(alunosLidos, sizeof(Aluno), NUM_ALUNOS, fp);
    fclose(fp);
    
    printf("\nDados apos modificacao:\n");
    for (j = 0; j < NUM_ALUNOS; j++)
    {
        printf("\nMatricula: %ld  Nome: %-8s      Notas:  ", alunosLidos[j].matricula, alunosLidos[j].nome);
        for (i = 0; i < 3; i++)
            printf("%6.2f ", alunosLidos[j].notas[i]);
        printf("\n");
    }
    return 0;
}

2. Modificação de Código

A função calcularProdutoSerie é projetada para calcular o valor de S, que representa o produto da série: S = (2/1 * 2/3) * (4/3 * 4/5) * (6/5 * 6/7) * ... ou equivalentemente S = produto_{n=1 até k} ( (2n)^2 / ((2n-1)*(2n+1)) ).

Por exemplo, quando k=10, o valor da função deverá ser aproximadamente: 1.533852.

Corrija os erros nas partes indicadas da função calcularProdutoSerie para que ela produza o resultado correto. Não altere a função main, não adicione nem remova linhas, e não altere a estrutura do programa.

#include <stdio.h>

// ERRO 1
void calcularProdutoSerie(int k)
{
    int nIteracao;
    float produtoTotal, num, den1, den2; // Variáveis float para precisão
    
    nIteracao = 1;
    produtoTotal = 1.0; // Inicializar com 1.0 para produto
    
    while (nIteracao <= k)
    {
        num = 2.0 * nIteracao;
        den1 = num - 1.0;
        den2 = num + 1.0;
        produtoTotal = produtoTotal * num * num / den1 / den2;
        nIteracao++;
    }
    // ERRO 2
    return produtoTotal
}

int main()
{
    printf("%f\n", calcularProdutoSerie(10));
    return 0;
}

3. Design de Função

Escreva a função somarSerie. Sua função é calcular a soma da seguinte série: S = 1/(1*2) + 1/(2*3) + 1/(3*4) + ... + 1/(n*(n+1)).

Por exemplo, quando n=10, o valor da função deverá ser aproximadamente 0.909091.

Não modifique a função main nem qualquer outra função. Insira apenas as instruções necessárias dentro das chaves da função somarSerie.

#include <stdio.h>

void funcaoAuxiliarNaoModificar(void); // Função auxiliar, não alterar

double somarSerie(int nTermos)
{
    // SEU CÓDIGO AQUI
}

int main()
{
    printf("%f\n", somarSerie(10));
    
    funcaoAuxiliarNaoModificar(); // Chamada da função auxiliar
    return 0;
}

void funcaoAuxiliarNaoModificar(void)
{
    /* Esta função é usada para abrir arquivos, inserir dados, chamar a função, exibir dados e fechar arquivos. */
    FILE *leituraArquivo, *escritaArquivo;
    int i, n;
    double resultadoSoma;
    
    leituraArquivo = fopen("entrada.dat", "r");
    escritaArquivo = fopen("saida.dat", "w");
    
    if (!leituraArquivo || !escritaArquivo) {
        perror("Erro ao abrir arquivos");
        return;
    }
    
    for (i = 0; i < 10; i++)
    {
        if (fscanf(leituraArquivo, "%d", &n) != 1) break;
        resultadoSoma = somarSerie(n);
        fprintf(escritaArquivo, "%f\n", resultadoSoma);
    }
    fclose(leituraArquivo);
    fclose(escritaArquivo);
}

Soluções para o Conjunto 80

1. Preenchimento de Código:

    while (!feof(fp)) // ___1___
    {
        // ...
        if (alunoLido.matricula == matriculaAlvo) // ___2___
            break;
    }
    // ...
    fseek(fp, -1L * sizeof(Aluno), SEEK_CUR); // ___3___

2. Modificação de Código:

double calcularProdutoSerie(int k) // ERRO 1 Corrigido: Tipo de retorno deve ser float ou double
{
    // ...
    return produtoTotal; // ERRO 2 Corrigido: Ponto e vírgula ausente
}

3. Design de Função:

double somarSerie(int nTermos)
{
    double somaAcumulada = 0.0;
    int i;
    for (i = 1; i <= nTermos; i++)
    {
        somaAcumulada += 1.0 / ((double)i * (i + 1));
    }
    return somaAcumulada;
}

Tags: C programming C exercises File I/O string manipulation array manipulation

Publicado em 8-7 19:06