Carattere di redirezione in C

tommy1996q
Ho un piccolo problema con i caratteri di redirezione in C. Ho scritto un semplicissimo programma che mi prende un numero e stampa il numero moltiplicato per 2:

#include

main(){
int n;
scanf("%d",&n);
printf("%d",2*n);
}

compilo e ottengo l'eseguibile a.exe, mentre creo un file a.txt dove scrivo un numero, per esempio 5.

Se faccio ./a.exe Allo stesso modo se faccio ./a.exe>a.txt, mi prende l'input da schermo e mi sovrascrive su a.txt il risultato

Però non capisco come prendere un input da file e scrivere il risultato sullo stesso file.
Ho provato a fare ./a.exea.txt,ma mi ritrovo 0 su file e non capisco perchè...
Grazie dell'aiuto!

Risposte
vict85
Tu stai usando dei comandi della prompt per gestire i file, insomma non ha nulla a che fare con il linguaggio che hai usato. Per farlo direttamente dal C devi usare i puntatori a FILE e funzioni specifiche. È un processo più controllato ma anche più laborioso.

claudio862
Come dice vict85, chi implementa le due redirezioni qui è la shell (Prompt dei comandi, bash, quello che usi per lanciare i tuoi programmi).
Quanto dai il comando "./a.exea.txt" la shell fa queste cose:
- vede che c'è un carattere <, quindi apre il relativo file di input a.txt
- vede che c'è un carattere >, quindi crea un nuovo file vuoto di output a.txt e lo apre
- esegue a.exe assegnando allo standard input e allo standard output lo stesso file a.txt (che adesso è vuoto).

Onestamente non so in che ordine apra i due file (input e output), né se sia possibile aprire quello di input e sovrascriverlo con quello di output ma facendo funzionare il tutto (probabilmente dipende dal sistema).

In breve: usa due file diversi per input e output: a.exeb.txt

tommy1996q
Il fatto è che dovrei prendere input da un file e scrivere sullo stesso file, ho provato di tutto, ma mi da come risultato 0, un file vuoto o addirittura -1(?)... Se riesco a risolvere vi faccio sapere

vict85
Lo puoi fare nel C in questo modo (ho aggiunto un po' di test sugli errori).

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    if (argc == 2)  // controlla che il numero di parametri si corretto
    {
        FILE *fp = fopen(argv[1], "r");
        if (!fp)
        {
            perror("Errore nella apertura del file in lettura");
            return EXIT_FAILURE;
        }

        int num = 0;
        if (fscanf(fp, "%d", &num) != 1)
        {
            fclose(fp);
            puts("Errore nella lettura dei dati nel file");
            return EXIT_FAILURE;
        }

        fclose(fp);
        fp = fopen(argv[1], "w");   // apre e cancella il contenuto del file
        if (!fp)
        {
            perror("Errore nella apertura del file in scrittura");
            return EXIT_FAILURE;
        }

        if (fprintf(fp, "%d", 2 * num) <= 0)
        {
            fclose(fp);
            puts("Errore nella scrittura dei dati nel file");
            return EXIT_FAILURE;
        }

        fclose(fp);
    }
    else
    {
        puts("ERRORE: numero di parametri errato");
        return EXIT_FAILURE;
    }
}


Dopo la compilazione lo lanci come
a.exe a.txt
separati da uno spazio.

tommy1996q
grazie mille vict85, adesso mi guarderò per bene il codice. Solo una domanda: a un certo punto quando fai
fp = fopen(argv[1], "w"); // apre e cancella il contenuto del file

perchè si cancella il contenuto del file, perchè apro in modalità "w"??? Se volessi invece solo sovrascrivere certi caratteri del file senza cancellare tutto all'apertura come dovrei fare?

apatriarca
Ci sono molte ragioni per cui la modifica "in place" di un file sia una cattiva idea. Molti programmi che modificano i file in realtà creano un file temporaneo che viene poi rinominato come il file precedente. In questo modo non corrompi ad esempio il file in caso di crash del programma o del sistema. Per rinominare un file in C puoi usare remove per cancellare il vecchio file e poi usare rename per rinominare il nuovo file che hai creato. Usare rename con un file già esistente potrebbe funzionare ma dipende dall'implementazione.

behemoth1
"tommy1996q":


[snip]

Però non capisco come prendere un input da file e scrivere il risultato sullo stesso file.
Ho provato a fare ./a.exea.txt,ma mi ritrovo 0 su file e non capisco perchè...
Grazie dell'aiuto!


Standard input/output, questa è la parola magica. Studia in tal senso, la rete è piena di materiale.

E' inutile fornire una riposta sulla redirezione se non si hanno le base su cos'è uno stream.

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.