Risolto Esercizio con nomi in C

KHAN21

Utente Bronze
9 Gennaio 2021
35
16
1
25
Buongiorno, mi è stato dato come esercizio il creare una lista con dei nomi all'interno in ordine alfabetico dati in input, e dato un altro nome, stampare tutti i nomi cui iniziali sono dopo quella del nome dato in input(per esempio se nella lista ho Arcibaldo e Bertoldo, dato in input Anghistantte, dovrebbe essere stampato a video Bertoldo. Il mio codice funziona su tutto, tranne che sulla parte dello stampare il valore del nome, cui stampa ma con valori spazzatura. Ringrazio anticipatamente per le risposte.
C:
#include <stdio.h>
#include <stdlib.h>
int lArr();
char *studenti(int);

int main()
{
  int index;int start;
  int n = lArr();
    char *studentiPtr = studenti(n);
    char alfa[] = {"abcdefghijklmnopqrstuvwxyz"};
    printf("inserisci la lunghezza del nome: ");
    scanf("%d", &index);
    char nome[index];
    printf("inserisci il nome: ");
    scanf("%s", nome);
    char l = nome[0];
    for (int i = 0;i < 26;i++){
        if (l == alfa[i]){
            start = i;
        }
  }
  for (int k = 0;k < n;k++){
    if (k > start){
      printf("%s\n", &studentiPtr[k]);
    }
    return 0;
}

}

int lArr(){
  int a;
    printf("inserisci il numero di studenti che poi metterai in ordine alfabetico: ");
    scanf("%d", &a);
  return a;
}

char *studenti(int a){
  char *arr;
    arr = (char *) malloc(sizeof(char)*a);
    for (int i = 0;i < a;i++){
        printf("inserisci il nome dello studente: ");
        scanf("%s", &arr[i]);
    printf("%s\n", &arr[i]);
    }
    return arr;
}
 

St3ve

Utente Jade
12 Ottobre 2011
2,339
5
1,682
683
scanf("%d", &index);
char nome[index];
Questo è un errore abbastanza comune. In C gli array devono avere una dimensione costante, mentre il tuo index è una variabile: stai creando un VLA, che non è proprio la stessa cosa. Per leggere un solo nome puoi fare una cosa del genere:
C:
#define MAXLEN 32
char nome[MAXLEN];          
printf("Inserisci un nome: ");
scanf("%s", nome);
Se vuoi leggere tanti nomi devi creare una matrice di caratteri, che può essere creata sia come array di array che come unico array (implicitamente bidimensionale). Ti propongo l'array unico:
C:
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 32

int main() {
  int n;
  printf("Quanti studenti vuoi inserire? ");
  scanf("%d", &n);

  char *studenti = malloc(sizeof(char) * MAXLEN * n);
  printf("Inserisci il nome degli %d studenti\n", n);
  for (int i = 0; i < n; i++) {
    printf("%d° studente: ", i + 1);
    scanf("%s", studenti + MAXLEN * i);
  }

  printf("Hai inserito:");
  for (int i = 0; i < n; i++) {
    printf(" %s", studenti + MAXLEN * i);
    putchar(i < n - 1 ? ',' : '\n');
  }

  free(studenti);
  return 0;
}

Se c'è qualcosa che non capisci avvisa che provo a spiegartelo, altrimenti prova a modificare il tuo codice seguendo il mio esempio.

PS. In realtà quell'array alfa non ti serve a niente, però inizia a risolverlo a modo tuo... poi ne discutiamo.
 

KHAN21

Utente Bronze
9 Gennaio 2021
35
16
1
25
Questo è un errore abbastanza comune. In C gli array devono avere una dimensione costante, mentre il tuo index è una variabile: stai creando un VLA, che non è proprio la stessa cosa. Per leggere un solo nome puoi fare una cosa del genere:
C:
#define MAXLEN 32
char nome[MAXLEN];          
printf("Inserisci un nome: ");
scanf("%s", nome);
Se vuoi leggere tanti nomi devi creare una matrice di caratteri, che può essere creata sia come array di array che come unico array (implicitamente bidimensionale). Ti propongo l'array unico:
C:
#include <stdio.h>
#include <stdlib.h>
#define MAXLEN 32

int main() {
  int n;
  printf("Quanti studenti vuoi inserire? ");
  scanf("%d", &n);

  char *studenti = malloc(sizeof(char) * MAXLEN * n);
  printf("Inserisci il nome degli %d studenti\n", n);
  for (int i = 0; i < n; i++) {
    printf("%d° studente: ", i + 1);
    scanf("%s", studenti + MAXLEN * i);
  }

  printf("Hai inserito:");
  for (int i = 0; i < n; i++) {
    printf(" %s", studenti + MAXLEN * i);
    putchar(i < n - 1 ? ',' : '\n');
  }

  free(studenti);
  return 0;
}

Se c'è qualcosa che non capisci avvisa che provo a spiegartelo, altrimenti prova a modificare il tuo codice seguendo il mio esempio.

PS. In realtà quell'array alfa non ti serve a niente, però inizia a risolverlo a modo tuo... poi ne discutiamo.
scusa se ti disturbo ancora, ma come si usano gli VLA?
 

St3ve

Utente Jade
12 Ottobre 2011
2,339
5
1,682
683
I VLA si usano esattamente come stavi facendo. Al posto di scrivere queste 4 righe:
C:
#define MAXLEN 32
char nome[MAXLEN];
printf("Inserisci un nome: ");
scanf("%s", nome);
dovrai scrivere queste 6 righe:
C:
int index;
printf("inserisci la lunghezza del nome: ");
scanf("%d", &index);
char nome[index];
printf("inserisci il nome: ");
scanf("%s", nome);
Quindi hai un codice più lungo da scrivere, crei un programma meno user-friendly perché ho un dato in più da inserire e devo contare a mano le lettere del nome e se l'utente inserisce il numero sbagliato o un numero negativo o se fa qualche altra furbata di questo tipo hai una problema di sicurezza conosciuto come stack buffer overflow (la tecnica di exploitation più famosa al mondo). Senza contare che non ti risolve il problema descritto nella seconda parte del messaggio: li i VLA hanno un po' più senso, ma non li stavi usando tu e non li ho introdotti io perché probabilmente è un esercizio sull'uso della malloc (e in ogni caso i VLA non si usano praticamente mai).
 

KHAN21

Utente Bronze
9 Gennaio 2021
35
16
1
25
I VLA si usano esattamente come stavi facendo. Al posto di scrivere queste 4 righe:
C:
#define MAXLEN 32
char nome[MAXLEN];
printf("Inserisci un nome: ");
scanf("%s", nome);
dovrai scrivere queste 6 righe:
C:
int index;
printf("inserisci la lunghezza del nome: ");
scanf("%d", &index);
char nome[index];
printf("inserisci il nome: ");
scanf("%s", nome);
Quindi hai un codice più lungo da scrivere, crei un programma meno user-friendly perché ho un dato in più da inserire e devo contare a mano le lettere del nome e se l'utente inserisce il numero sbagliato o un numero negativo o se fa qualche altra furbata di questo tipo hai una problema di sicurezza conosciuto come stack buffer overflow (la tecnica di exploitation più famosa al mondo). Senza contare che non ti risolve il problema descritto nella seconda parte del messaggio: li i VLA hanno un po' più senso, ma non li stavi usando tu e non li ho introdotti io perché probabilmente è un esercizio sull'uso della malloc (e in ogni caso i VLA non si usano praticamente mai).
ok, provo senza usare i VLA, se ho problemi scrivo, grazie mille per l'aiuto :)