Domanda

Sto leggendo il libro K & amp; R, e sono un po 'bloccato.

Cosa c'è di sbagliato in quanto segue?

void getInput(int* output) {
   int c, i;
   for(i=0; (c = getchar()) != '\n'; i++)
     output[i] = c; // printf("%c", c) prints the c value as expected
   output[++i] = '\0';
}

Quando eseguo il programma non esce mai dal ciclo e devo uscire da Ctrl + C . Tuttavia, se sostituisco la quinta riga con printf ("% c " ;, c); , stampa tutto l'input bene dopo aver premuto invio e creato la nuova riga.

È stato utile?

Soluzione

  

Cosa c'è di sbagliato in quanto segue?

1. void getInput(int* output) {

Perché l'argomento di input è un int * quando ciò che si desidera memorizzare in una matrice di caratteri? Probabilmente

void getInput(char* output) {

è migliore.

Inoltre, come fai a sapere che il puntatore di output punta da qualche parte dove hai abbastanza memoria per scrivere l'input dell'utente? Forse è necessario avere la lunghezza massima del buffer come parametro aggiuntivo per evitare errori di overflow del buffer come PW sottolineato .

5.   output[++i] = '\0';

Sono già stato incrementato di un ulteriore tempo all'interno del ciclo for, quindi puoi semplicemente fare:

output[i] = '\0';

Oltre a questi, il programma funziona bene e produce ciò che inseriamo fino al ritorno.

FWIW, l'ho provato chiamandolo così:

 int main(void)
{
    char o[100];
    getInput(o);
    printf("%s", o);
    return 0;
}

Altri suggerimenti

Mi sembra corretto come scritto, tranne per il fatto che non è necessario incrementare i al di fuori del ciclo. L'i viene incrementato subito prima dell'uscita dal ciclo, quindi è già dove lo desideri.

Assicurati che un '\ n' lo stia effettivamente trasformando in c.

A volte un '\ n' viene eliminato come delimitatore.

il tuo ultimo codice pubblicato contiene 3 errori che posso vedere:

char* userInput[MAX_INPUT_SIZE];

Dovrebbe essere:

char userInput[MAX_INPUT_SIZE+1];

(questo è già stato menzionato da Pax Diablo)

getInput(&userInput);

Dovrebbe essere:

getInput( userInput );

Quest'ultimo errore indica che hai passato a getInput un indirizzo all'interno dello stack di chiamate. hai una sovrascrittura della memoria. probabilmente una delle tue chiamate a getchar () ritorna all'indirizzo sbagliato.

un modo semplice per rischiare l'overflow del buffer, poiché le dimensioni dell'output non vengono mai passate / verificate

Hai provato a usare un debugger? Dovresti scorrere il codice in gdb o visual studio o qualunque cosa tu stia usando e vedere cosa sta succedendo. Hai detto che eri un principiante, quindi forse non lo avevi ancora considerato - questa è una tecnica di debug abbastanza normale da usare.

Ecco il programma completo con un paio di aggiornamenti dal tuo input, ma non riuscirà comunque a uscire dal ciclo. A proposito, questo è stato l'esercizio 1-24 a pag. 34

#include <stdio.h>

#define STACK_SIZE 50
#define MAX_INPUT_SIZE 1000
#define FALSE 0
#define TRUE 1

void getInput();
int validInput();

int main() {
  char* userInput[MAX_INPUT_SIZE];

  getInput(&userInput);

  if (validInput(&userInput) == TRUE)
    printf("Compile complete");
  else
    printf("Error");
}

// Functions
void getInput(char* output) {
  int c, i;
  for(i=0; (c = getchar()) != '\n' && c != EOF && i <= MAX_INPUT_SIZE; i++)
    output[i] = c;
  output[i] = '\0';
}

int validInput(char* input) {
  char stack[STACK_SIZE];
  int c;
  int j;

  for (j=0; (c = input[j]) != '\0'; ) {
    switch(c){
      case '[': case '(': case '{':
        stack[j++] = c;
        break;
      case ']': case ')': case '}':
        if (c == ']' && stack[j] != '[')
          return FALSE;
        else if (c == '}' && stack[j] != '{')
          return FALSE;
        else if (c == ')' && stack[j] != '(')
          return FALSE;

        // decrement the stack's index  
        --j;
        break;
    }
  }

  return TRUE;
}

Ecco il codice di lavoro finale. Devo dire che ho preso un bel po 'dal farlo. Grazie per l'aiuto e i suggerimenti.

Qualche suggerimento su come le cose potrebbero essere fatte meglio?

#include <stdio.h>

#define STACK_SIZE 50
#define MAX_INPUT_SIZE 1000
#define FALSE 0
#define TRUE !FALSE

void get_input();
int valid_input();

int main() {
  char user_input[MAX_INPUT_SIZE + 1]; // +1 for the \0

  get_input(user_input);

  if (valid_input(user_input))
    printf("Success\n");
  else
    printf("Error\n");
}

// Functions
void get_input(char* output) {
  int c, i;
  for(i=0; (c = getchar()) != '\n' && c != EOF && i <= MAX_INPUT_SIZE; i++)
    output[i] = c;
  output[i] = '\0';
}

int valid_input(char* input) {
  char stack[STACK_SIZE];
  char c;
  int i = 0;
  int stack_index = -1;

  while ((c = input[i]) != '\0' && i < STACK_SIZE) {
    switch(c){
      case '[': case '(': case '{':
        stack_index++; 
        stack[stack_index] = c;
        break;
      case ']': case ')': case '}':
        if ((c == ']' && stack[stack_index] != '[') ||
            (c == '}' && stack[stack_index] != '{') ||
            (c == ')' && stack[stack_index] != '('))
          return FALSE;

        // decrement the stack's index now that the closing bracket is found  
        stack_index--;
        break;
    }
    i++;
  }

  // stack index should be back where it started
  return (stack_index == -1);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top