C standard di basso livello-in per accettare il nome del file, quindi stampare il contenuto del file su stdout

Voglio ottenere un nome file da un utente tramite stdin, aprire il file con open () e assegnarlo a un descrittore di file, quindi stampare il contenuto di quel file su stdout. Questo è il mio codice e non funziona correttamente.

I problemi:

  1. il printf (“immetti nomefile”); la dichiarazione non viene mai mostrata
  2. non apre mai il file; invece qualunque sia l’input dell’utente viene stampato sullo schermo e quindi il messaggio di errore “no tale file o directory” viene stampato e il programma viene chiuso
  3. dopo che il programma esiste vedo “inserisci il nome del file” stampato prima del prompt nel terminale

CODICE:

{ printf("Enter the filename: "); read(STDIN_FILENO, userInput, sizeof(userInput)); if((input_file1 = open(userInput, O_RDONLY))  0) { if((write(STDOUT_FILENO, buffer, n)) < 0) { perror("failed to write to standard-out"); close(input_file1); exit(1); } } } 

Console:

 machine{user1}168: ls // to show that the file exists a.out backup file1 machine{user1}170: ./a.out file1 // this is user input file1 // this is printed for no reason : No such file or directory // ???? Enter the filename: machine{user1}171: // now the prompt is printed...? 

routine di input / output sono bufferizzate (vedi stdio (3) & setbuf (3) . Devi chiamare fflush (3) (su libc recente, è implicitamente chiamato per stdout se leggi con fgets o scanf ) E dovresti davvero evitare di mescolare i descrittori di file e le maniglie FILE sullo stesso output o input (vedi fileno (3) ma chiama sempre fflush ….). Sostituisci

  printf("Enter the filename: "); read(STDIN_FILENO, userInput, sizeof(userInput)); 

con

  printf("Enter the filename: \n"); fflush(NULL); if (!fgets(userInput,sizeof(userInput),stdin)) { perror("fgets"); exit(EXIT_FAILURE); }; 

In realtà qui la fflush potrebbe essere evitata se si mantiene l’importantissimo terminando \n (newline). Se non vuoi una nuova riga dovresti chiamare fflush (ma alcuni libc lo chiamano per te).

Chiamare fflush troppo o troppo spesso è molto meno dannoso (perché su tutto il stream già scaricato è un no-op) piuttosto che chiamarlo troppo piccolo o non abbastanza.

Ma dovresti sapere su getline (3) (per evitare linee a lunghezza fissa). Su sistemi Linux e GNU vale la pena usare readline : ti permette di dare un prompt sexy e il tuo utente a modificare la riga dattiloscritta.

Il prompt non viene mai visualizzato perché si utilizza read() anziché una delle funzioni I / O standard ( scanf() , fgets() , ecc.) Per ottenere l’input. fflush(stdout) funzione di input o usare fflush(stdout) o fflush(0) prima di chiamare read() .

La tua lettura include la nuova riga, quindi l’open tenta di aprire il file con una nuova riga alla fine del nome. Quel file non esiste, quindi l’open fallisce.

 { printf("Enter the filename: "); if (fgets(userInput, sizeof(userInput), stdin) == 0) { fprintf(stderr, "Oops!\n"); exit(1); } userInput[strlen(userInput)-1] = '\0'; if ((input_file1 = open(userInput, O_RDONLY)) < 0) { perror(userInput); exit(1); } while ((n = read(input_file1, buffer, sizeof(buffer))) > 0) { if (printf("%.*s", n, buffer)) != n) { perror("failed to write to standard-out"); close(input_file1); exit(1); } } close(input_file1); }