txt - string en c



Cómo leer una línea desde la consola en C? (9)

Cómo leer una línea desde la consola en C?

  • Construir su propia función , es una de las maneras que lo ayudaría a lograr leer una línea desde la consola en C.

  • Estoy usando la asignación de memoria dinámica para asignar solo la cantidad de memoria necesaria para contener todos los caracteres de una línea junto con el carácter '\0' .

  • Y aquí estoy usando un bucle para escanear cada carácter de la cadena uno por uno usando la función getchar() hasta que el usuario ingrese '\n' o el carácter EOF

    //the function to read lines of variable length
    
    char* scan_line(char *line)
    {
        int ch; //as getchar() returns `int`
    
        if( (line = malloc(sizeof(char))) == NULL) //allocating memory
        {
            //checking if allocation was successful or not
            printf("unsuccessful allocation");
            exit(1);
        }
    
        line[0]='\0';
    
        for(int index = 0; ( (ch = getchar())!='\n' ) && (ch != EOF) ; index++)
        {
            if( (line = realloc(line, (index + 2)*sizeof(char))) == NULL )
            {
                //checking if reallocation was successful or not
                printf("unsuccessful reallocation");
                exit(1);
            }
    
            line[index] = (char) ch; //type casting `int` to `char`
            line[index + 1] = '\0'; //inserting null character at the end
        }
    
        return line;
    }  
    
  • Ahora puedes leer una línea completa de esta manera:

    char *line = NULL;
    line = scan_line(line);
    

Aquí hay un programa de ejemplo que usa la función scan_line() :

#include <stdio.h>
#include <stdlib.h> //for dynamic allocation functions

char* scan_line(char *line)
{
    ..........
}

int main(void)
{
    char *a = NULL;

    a = scan_line(a); //function call to scan the line

    printf("%s\n",a); //printing the scanned line

    free(a); //don't forget to free the malloc'd pointer
}

muestra de entrada:

Twinkle Twinkle little star.... in the sky!

muestra de salida:

Twinkle Twinkle little star.... in the sky!

https://code.i-harness.com

¿Cuál es la forma más sencilla de leer una línea completa en un programa de consola en C? El texto ingresado puede tener una longitud variable y no podemos hacer ninguna suposición sobre su contenido.


Algo como esto:

unsigned int getConsoleInput(char **pStrBfr) //pass in pointer to char pointer, returns size of buffer
{
    char * strbfr;
    int c;
    unsigned int i;
    i = 0;
    strbfr = (char*)malloc(sizeof(char));
    if(strbfr==NULL) goto error;
    while( (c = getchar()) != '\n' && c != EOF )
    {
        strbfr[i] = (char)c;
        i++;
        strbfr = (void*)realloc((void*)strbfr,sizeof(char)*(i+1));
        //on realloc error, NULL is returned but original buffer is unchanged
        //NOTE: the buffer WILL NOT be NULL terminated since last
        //chracter came from console
        if(strbfr==NULL) goto error;
    }
    strbfr[i] = '\0';
    *pStrBfr = strbfr; //successfully returns pointer to NULL terminated buffer
    return i + 1; 
    error:
    *pStrBfr = strbfr;
    return i + 1;
}

En sistemas BSD y Android también puedes usar fgetln :

#include <stdio.h>

char *
fgetln(FILE *stream, size_t *len);

Al igual que:

size_t line_len;
const char *line = fgetln(stdin, &line_len);

La line no tiene terminación nula y contiene \n (o lo que sea que use su plataforma) al final. Se vuelve inválido después de la siguiente operación de E / S en la transmisión.


Entonces, si buscaba argumentos de comando, eche un vistazo a la respuesta de Tim. Si solo quieres leer una línea desde la consola:

#include <stdio.h>

int main()
{
  char string [256];
  printf ("Insert your full address: ");
  gets (string);
  printf ("Your address is: %s\n",string);
  return 0;
}

Sí, no es seguro, puedes sobrepasar el búfer, no verifica el final del archivo, no admite codificaciones y muchas otras cosas. En realidad, ni siquiera pensé si esto CUALQUIERA de estas cosas. Estoy de acuerdo, me equivoqué :) Pero ... cuando veo una pregunta como "¿Cómo leer una línea desde la consola en C?", Supongo que una persona necesita algo simple, como get () y no 100 líneas de código como arriba. En realidad, creo que si tratas de escribir esas 100 líneas de código en realidad, cometerías muchos más errores de los que hubieras hecho si hubieras elegido;)


Esta función debe hacer lo que quieras:

char* readLine( FILE* file )
 {
 char buffer[1024];
 char* result = 0;
 int length = 0;

 while( !feof(file) )
  {
  fgets( buffer, sizeof(buffer), file );
  int len = strlen(buffer);
  buffer[len] = 0;

  length += len;
  char* tmp = (char*)malloc(length+1);
  tmp[0] = 0;

  if( result )
   {
   strcpy( tmp, result );
   free( result );
   result = tmp;
   }

  strcat( result, buffer );

  if( strstr( buffer, "\n" ) break;
  }

 return result;
 }

char* line = readLine( stdin );
/* Use it */
free( line );

Espero que esto ayude.


Me encontré con el mismo problema hace un tiempo, esta fue mi solución, espero que ayude.

/*
 * Initial size of the read buffer
 */
#define DEFAULT_BUFFER 1024

/*
 * Standard boolean type definition
 */
typedef enum{ false = 0, true = 1 }bool;

/*
 * Flags errors in pointer returning functions
 */
bool has_err = false;

/*
 * Reads the next line of text from file and returns it.
 * The line must be free()d afterwards.
 *
 * This function will segfault on binary data.
 */
char *readLine(FILE *file){
    char *buffer   = NULL;
    char *tmp_buf  = NULL;
    bool line_read = false;
    int  iteration = 0;
    int  offset    = 0;

    if(file == NULL){
        fprintf(stderr, "readLine: NULL file pointer passed!\n");
        has_err = true;

        return NULL;
    }

    while(!line_read){
        if((tmp_buf = malloc(DEFAULT_BUFFER)) == NULL){
            fprintf(stderr, "readLine: Unable to allocate temporary buffer!\n");
            if(buffer != NULL)
                free(buffer);
            has_err = true;

            return NULL;
        }

        if(fgets(tmp_buf, DEFAULT_BUFFER, file) == NULL){
            free(tmp_buf);

            break;
        }

        if(tmp_buf[strlen(tmp_buf) - 1] == '\n') /* we have an end of line */
            line_read = true;

        offset = DEFAULT_BUFFER * (iteration + 1);

        if((buffer = realloc(buffer, offset)) == NULL){
            fprintf(stderr, "readLine: Unable to reallocate buffer!\n");
            free(tmp_buf);
            has_err = true;

            return NULL;
        }

        offset = DEFAULT_BUFFER * iteration - iteration;

        if(memcpy(buffer + offset, tmp_buf, DEFAULT_BUFFER) == NULL){
            fprintf(stderr, "readLine: Cannot copy to buffer\n");
            free(tmp_buf);
            if(buffer != NULL)
                free(buffer);
            has_err = true;

            return NULL;
        }

        free(tmp_buf);
        iteration++;
    }

    return buffer;
}

Si está utilizando la biblioteca C de GNU u otra biblioteca compatible con POSIX, puede usar getline() y pasarle stdin para la secuencia de archivos.


Una implementación muy simple pero insegura para leer líneas para la asignación estática:

char line[1024];

scanf("%[^\n]", line);

Una implementación más segura, sin la posibilidad de desbordamiento de búfer, pero con la posibilidad de no leer toda la línea, es:

char line[1024];

scanf("%1023[^\n]", line);

No es la 'diferencia en uno' entre la longitud especificada que declara la variable y la longitud especificada en la cadena de formato. Es un artefacto histórico.


Necesita gestión dinámica de la memoria y utilizar la función fgets para leer su línea. Sin embargo, parece que no hay forma de ver cuántos caracteres lee. Entonces usas fgetc:

char * getline(void) {
    char * line = malloc(100), * linep = line;
    size_t lenmax = 100, len = lenmax;
    int c;

    if(line == NULL)
        return NULL;

    for(;;) {
        c = fgetc(stdin);
        if(c == EOF)
            break;

        if(--len == 0) {
            len = lenmax;
            char * linen = realloc(linep, lenmax *= 2);

            if(linen == NULL) {
                free(linep);
                return NULL;
            }
            line = linen + (line - linep);
            linep = linen;
        }

        if((*line++ = c) == '\n')
            break;
    }
    *line = '\0';
    return linep;
}

Nota : ¡Nunca use gets! No hace controles de límites y puede desbordar tu memoria intermedia





readline