Autor
|
Tema: Forma canonica (Leído 2,208 veces)
|
txiki481
Desconectado
Mensajes: 4
|
Buenas, estoy haciendo un programa que dandole una posición y un fichero, escribe lo que pongas en la terminal y lo escribe en la posición introducida.
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h>
#define BUFFER_TAMAINA 512
main(int argc, const char * argv[]) { int a; int f,k; char buff[BUFFER_TAMAINA]; FILE *f1;
if (argc==3) { if (strcmp(argv[2],"0")!=0 && atoi(argv[2])==0) { write(1, "error, la posicion no es un numero\n", 36); exit(1); }
f1=fopen(argv[1], "r+");
if(errno==ENOENT) { write(1, "el fichero no existe\n", 28); exit(1); } while(fgetc(f1)!=EOF){k++;} fclose(f1);
if((atoi(argv[2]))>k) { write(1,"la position es demasiado alta\n",28); exit(1); } if(atoi(argv[2])<0){ write(1, "la position es negativa\n", 31); exit(1); }
f = open(argv[1], O_WRONLY,00777);
if(errno==ENOENT){ write(1, "el fichero no existe\n", 28); exit(1); }
lseek(f, atoi(argv[2]), SEEK_SET);
while ((a=read(0,buff,BUFFER_TAMAINA))>0) { write(f,buff,a); }
close(f); } else { write(1,"Erabilera: ./idatzi_fitx [fichero] [posicion]\n",50); } }
El problema es que en la terminal hay que darle al enter para que lo escriba, es decir esta hecho de manera canónica, y coge tambien el intro como todo lo que queremos escribir. Como podría hacer para que no tuviera en cuenta el enter?
Y como podría hacerlo de forma no canónica? Es decir, que todo lo que vaya escribiendo en la terminal se vaya escribiendo sin necesidad de darle al enter.
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
Eso depende del terminal, no hay una forma estándar para todo el mundo. Si tienes *nix se hace de una forma, en Windows de otra...
|
|
|
En línea
|
|
|
|
txiki481
Desconectado
Mensajes: 4
|
de la forma de unix como seria
|
|
|
En línea
|
|
|
|
|
txiki481
Desconectado
Mensajes: 4
|
Solo me coge un caracter, le doy a cualquier letra y se acaba el programa guardando la letra en la posición introducida. Como hago para escribir todo lo que quiera?
#include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <termios.h>
#define BUFFER_TAMAINA 512
void SetTermNoCanon( struct termios *SavedTM) { struct termios tm;
tcgetattr(0, &tm); tcgetattr(0, SavedTM); tm.c_lflag &= ~(ICANON|ECHO); tm.c_cc[VMIN]= 1; tm.c_cc[VTIME]= 0; tcsetattr(0, TCSANOW, &tm);
}
int main(int argc, const char * argv[]) { int a; int f,k; char buff[BUFFER_TAMAINA]; int p = atoi(buff); // FILE *f1;
struct stat *stat1; struct termios saved_tm;
if (argc==3) { if (strcmp(argv[2],"0")!=0 && atoi(argv[2])==0) { write(1, "error, la posicion no es un numero\n", 36); exit(1); }
f1=fopen(argv[1], "r+");
if(errno==ENOENT) { write(1, "el fichero no existe\n", 28); exit(1); } while(fgetc(f1)!=EOF){k++;} fclose(f1);
if((atoi(argv[2]))>k) { write(1,"la position es demasiado alta\n",28); exit(1); } if(atoi(argv[2])<0){ write(1, "la position es negativa\n", 31); exit(1); }
f = open(argv[1], O_WRONLY,00777);
if(errno==ENOENT){ write(1, "el fichero no existe\n", 28); exit(1); }
lseek(f, atoi(argv[2]), SEEK_SET);
SetTermNoCanon( &saved_tm );
while ((a=read(0,buff,BUFFER_TAMAINA))>0) { if(stat(argv[1], &*stat1) != NULL) {
switch(p) { case 'q': tcsetattr(0, TCSANOW, &saved_tm); close(f); exit(0); case ' ': break; default: write(f,buff,a);
printf("Información:\n",argv[1]); printf("---------------------------\n"); printf("Tamaño: \t \t %d bytes\n", stat1->st_size); printf("Links: \t%d\n", stat1->st_nlink); printf("inode: \t \t %d\n", stat1->st_ino); } } }
tcsetattr(0, TCSANOW, &saved_tm); close(f); exit(0); } else { write(1,"Erabilera: ./idatzi_fitx [fichero] [posicion]\n",50); } }
|
|
|
En línea
|
|
|
|
MAFUS
Desconectado
Mensajes: 1.603
|
No tengo linux para probar el código, pero debería ser una cosa así: #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <termios.h> // Sacado de https://stackoverflow.com/questions/7469139/what-is-equivalent-to-getch-getche-in-linux static struct termios old, new; /* Initialize new terminal i/o settings */ void initTermios(int echo) { tcgetattr(0, &old); /* grab old terminal i/o settings */ new = old; /* make new settings same as old settings */ new.c_lflag &= ~ICANON; /* disable buffered i/o */ if (echo) { new.c_lflag |= ECHO; /* set echo mode */ } else { new.c_lflag &= ~ECHO; /* set no echo mode */ } tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */ } /* Restore old terminal i/o settings */ void resetTermios(void) { tcsetattr(0, TCSANOW, &old); } /* Read 1 character - echo defines echo mode */ char getch_(int echo) { char ch; initTermios(echo); resetTermios(); return ch; } /* Read 1 character without echo */ return getch_(0); } /* Read 1 character with echo */ char getche(void) { return getch_(1); } void SetTermNoCanon( struct termios *SavedTM) { struct termios tm; tcgetattr(0, &tm); tcgetattr(0, SavedTM); tm.c_lflag &= ~(ICANON|ECHO); tm.c_cc[VMIN]= 1; tm.c_cc[VTIME]= 0; tcsetattr(0, TCSANOW, &tm); } int main(int argc, const char * argv[]) { char c; int f; long file_end; long file_pos; char buff[BUFFER_TAMAINA]; FILE *f1; struct stat stat1; // Voy a sustituir todos los write a stdout por printf o puts // Número de argumentos diferente al esperado if (argc != 3) { printf("Uso: %s [fichero] [posicion]", argv [0]); return EXIT_FAILURE; } file_pos = atol(argv [2]); // No se pueden los metadatos del archivo if(stat(argv[1], &statl) == -1) { puts("error, no se pueden recuperar datos del archivo"); return EXIT_FAILURE; } // El argumento posición no es un número o es 0 if(file_pos < 1) { puts("error, posicion debe ser un entero igual o mayor a 1"); return EXIT_FAILURE; } f1 = fopen(argv [1], "r+"); // El archivo no existe o no se puede abrir if(!f1) { puts("error, el fichero no existe"); return EXIT_FAILURE; } //- Sustituyo todo esto // while(fgetc(f1)!=EOF) { // k++; // } // fclose(f1); //- Por lo siguiente // La posición entregada está fuera del archivo if(file_pos>file_end) { puts("error, la position es demasiado alta"); return EXIT_FAILURE; } fseek(f1 , file_pos , SEEK_SET ); SetTermNoCanon( &saved_tm ); while(c=getche()!=27) { } printf("Información: %s\n", argv [1]); printf("---------------------------\n"); printf("Tamaño: \t \t %d bytes\n", stat1 ->st_size ); printf("Links: \t%d\n", stat1 ->st_nlink ); printf("inode: \t \t %d\n", stat1 ->st_ino ); return EXIT_SUCCESS; }
|
|
|
En línea
|
|
|
|
|
|