如何阅读在C控制台一条线吗?如何阅读在C控制台一条线吗?(How to read a line fr

2019-05-10 13:51发布

什么是阅读一个C控制台程序输入的文本可能有一个可变长度的全线最简单的方法,我们不能对内容做任何假设。

Answer 1:

您需要动态内存管理,并使用fgets函数来读取你的路线。 然而,似乎没有办法,看看有多少个字符阅读。 所以,你使用龟etc:

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

注意 :不要使用gets! 它不会做边界检查,可以溢出您的缓冲区



Answer 2:

如果您使用的是GNU C库或其他兼容POSIX库,你可以使用getline()并通过stdin到它的文件流。



Answer 3:

一个非常简单的,但不安全的实现来读取静态分配线:

char line[1024];

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

一个更安全的实现,没有缓冲区溢出的可能性,但与不读整行的可能性是:

char line[1024];

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

未指定声明变量的长度和格式字符串指定的长度之间的“由一个差”。 这是一个历史的假象。



Answer 4:

您可能需要通过字符(GETC())循环使用的字符,以确保你没有缓冲区溢出,不截断输入。



Answer 5:

getline运行的例子

提到这个答案 ,但这里有一个例子。

这是POSIX 7 ,分配内存对我们来说,和很好的重用上循环分配的缓冲区。

指针newbs,这样说的: 为什么函数getline的第一个参数的指针,指针“字符**”,而不是“字符*”?

#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的实现

没有POSIX? 也许你想看看glibc的2.23实施 。

它解析为getdelim ,这是一个简单的POSIX超集getline与任意的行终止符。

双打每当需要增加分配的内存,并期待线程安全的。

它需要一定的宏观扩张,但你不可能做的更好。



Answer 6:

所以,如果你要找的命令参数,看看添的回答。 如果你只是想读从控制台线:

#include <stdio.h>

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

是的,它是不安全的,你可以做缓冲区溢出,它不检查文件结束,它不支持编码和其他很多东西。 其实我压根没想到它是否没有做过这方面的东西。 我同意我有点搞砸了:)但是...当我看到像“如何从控制台用C读取一条线吗?”的问题时,我想一个人需要简单的东西,像gets()函数,而不是100行代码像上面。 其实我觉得,如果你尝试写的100行的在现实中的代码,你会做更多的错误,比你会做这样的事,你得选择;)



Answer 7:

至于建议,你可以使用的getchar()从控制台读取,直到最终的行或EOF返回,建立自己的缓冲区。 成长的缓冲区,如果你不能设置一个合理的最大行大小可以动态地发生。

你可以用也用fgets作为一种安全的方式来获得线为C空值终止字符串:

#include <stdio.h>

char line[1024];  /* Generously large value for most situations */

char *eof;

line[0] = '\0'; /* Ensure empty line if no input delivered */
line[sizeof(line)-1] = ~'\0';  /* Ensure no false-null at end of buffer */

eof = fgets(line, sizeof(line), stdin);

如果您已用尽控制台输入或如果操作由于某种原因失败,则返回EOF == NULL和行缓冲可能会保持不变(这就是为什么设置第一个字符为“\ 0”是很方便的)。

与fgets不会溢出线[],它会确保有一个成功返回的最后一个接受的字符之后空。

如果的行结束为止,终止“\ 0”之前的字符将是一个“\ N”。

如果存在之前结束“\ 0”没有终止“\ n”也可以是,有更多的数据,或者下一个请求将报告结束文件。 你必须做的另一个与fgets,以确定哪个是哪个。 (在这一点上,在使用getchar循环()更容易。)

在(更新)例如上面的代码,如果成功与fgets后线[的sizeof(线)-1] ==“\ 0”,就知道该缓冲液完全填充。 如果该位置由“\ n”进行你知道你是幸运的。 否则,要么是更多的数据或档案结尾提前了在标准输入。 (当缓冲区没有完全填满,你仍然可能在最终文件中,有也可能不是一个“\ n”在当前行的末尾。既然你已经扫描字符串查找和/或消除串结束前的任何“\ n”(第一“\ 0”在缓冲液中),我倾向于使用的getchar()在第一位置更喜欢)。

你需要做的处理仍然有比你读的第一块量多行的内容。 可以由动态生长缓冲的实例与任一的getchar或与fgets上班。 有一些棘手的边界情况需要注意的(如记住有一个输入开始在的“\ 0”,结束之前的输入延长缓冲之前的位置存储)。



Answer 8:

很多人跟我一样,来到这个帖子什么是搜索标题匹配,虽然说明是怎么说的可变长度。 在大多数情况下,我们所知道的长度事先。

如果你知道前手的长度,请尝试以下:

char str1[1001] = { 0 };
fgets(str1, 1001, stdin); // 1000 chars may be read

来源: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm



Answer 9:

如何阅读在C控制台一条线吗?

  • 构建自己的功能 ,是的,这将有助于你实现用C从控制台读取线的方式之一。

  • 我使用动态内存分配 ,只是分配给持有一个行内的所有字符与沿所需的内存足够量的'\0'字符。

  • 这里我使用一个循环来扫描一个串中的每个字符由一个使用getchar()直到用户输入功能'\n'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; } 
  • 现在,你可以阅读完整的线是这样的:

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

下面是一个使用的示例程序 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
}

样品输入:

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

输出样本:

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


Answer 10:

我碰到了同样的问题来了,前一段时间,这是我solutuion,希望它帮助。

/*
 * 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;
}


Answer 11:

在BSD系统和Android也可以使用fgetln

#include <stdio.h>

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

像这样:

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

line是不是空终止,并包含\n到底(或任何平台使用)。 它成为投产的下一个I / O操作后无效。



Answer 12:

事情是这样的:

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


Answer 13:

这个函数应该做你想要什么:

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 );

我希望这有帮助。



文章来源: How to read a line from the console in C?