How to read a line from the console in C?

2019-01-01 00:40发布

What is the simplest way to read a full line in a C console program The text entered might have a variable length and we can't make any assumption about its content.

13条回答
笑指拈花
2楼-- · 2019-01-01 01:07

A very simple but unsafe implementation to read line for static allocation:

char line[1024];

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

A safer implementation, without the possibility of buffer overflow, but with the possibility of not reading the whole line, is:

char line[1024];

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

Not the 'difference by one' between the length specified declaring the variable and the length specified in the format string. It is a historical artefact.

查看更多
步步皆殇っ
3楼-- · 2019-01-01 01:09

On BSD systems and Android you can also use fgetln:

#include <stdio.h>

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

Like so:

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

The line is not null terminated and contains \n (or whatever your platform is using) in the end. It becomes invalid after the next I/O operation on stream.

查看更多
有味是清欢
4楼-- · 2019-01-01 01:11

You might need to use a character by character (getc()) loop to ensure you have no buffer overflows and don't truncate the input.

查看更多
姐姐魅力值爆表
5楼-- · 2019-01-01 01:11

How to read a line from the console in C?

  • Building your own function, is one of the way that would help you to achieve reading a line from console in C.

  • I'm using dynamic memory allocation to allocate just the sufficient amount of memory required to hold all the characters of a line along with the '\0' character.

  • And here I'm using a loop to scan each character of the string one by one using the getchar() function untill the user enters '\n' or EOF character

    //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;
    }  
    
  • Now you could read a full line this way :

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

Here's an example program using the scan_line() function :

#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
}

sample input :

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

sample output :

Twinkle Twinkle little star.... in the sky!
查看更多
临风纵饮
6楼-- · 2019-01-01 01:14

getline runnable example

Mentioned on this answer but here is an example.

It is POSIX 7, allocates memory for us, and reuses the allocated buffer on a loop nicely.

Pointer newbs, read this: Why is the first argument of getline a pointer to pointer "char**" instead of "char*"?

#define _XOPEN_SOURCE 700

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

int main(void) {
    char *line = NULL;
    size_t len = 0;
    ssize_t read = 0;
    while (read != -1) {
        puts("enter a line");
        read = getline(&line, &len, stdin);
        printf("line = %s", line);
        printf("line length = %zu\n", read);
        puts("");
    }
    free(line);
    return 0;
}

glibc implementation

No POSIX? Maybe you want to look at the glibc 2.23 implementation.

It resolves to getdelim, which is a simple POSIX superset of getline with an arbitrary line terminator.

It doubles the allocated memory whenever increase is needed, and looks thread-safe.

It requires some macro expansion, but you're unlikely to do much better.

查看更多
高级女魔头
7楼-- · 2019-01-01 01:18

So, if you were looking for command arguments, take a look at Tim's answer. If you just want to read a line from console:

#include <stdio.h>

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

Yes, it is not secure, you can do buffer overrun, it does not check for end of file, it does not support encodings and a lot of other stuff. Actually I didn't even think whether it did ANY of this stuff. I agree I kinda screwed up :) But...when I see a question like "How to read a line from the console in C?", I assume a person needs something simple, like gets() and not 100 lines of code like above. Actually, I think, if you try to write those 100 lines of code in reality, you would do many more mistakes, than you would have done had you chosen gets ;)

查看更多
登录 后发表回答