C 从 stdin 读取行

C reading lines from stdin

我的目标是使用 getline() 函数从管道 .txt 文件中读取每一行,但每次使用此函数时我都会以某种方式收到错误:

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

int main() {
  int Chars;
  int size = 10;
  char *string;

  printf("Please enter a string: ");
  string = (char*) malloc(size);
  Chars = getline(&string, &size, stdin);

  if (Chars == -1)
  {
    puts("ERROR!");
  }
  else
  {
    puts("You entered the following string: ");
    puts(string);
    printf("\nCurrent size for string block: %d", Chars);
  }
  return 0;
}

我总是收到错误代码:[错误] Id retruned 1 退出状态

我在 DevC++ 上重现了链接错误,其中 getline() 似乎丢失了,即使在使用 gcc[ 强制最近的 C 修订后也是如此=54=] 编译器选项,例如 -std=c11.

所以我用 fgets():

重写了你的代码
char *fgets(char *s, int size, FILE *stream);

它肯定比 getline 更便携,但有一些区别:

  • 如果在此限制之前没有遇到换行符,它最多读取 size-1 个字符(它会自动附加字符串终止符)。所以它不管理缓冲区重新分配
  • 结果字符串包含 '\n' 个字符,如果找到
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX_STR_SIZE 32

int main( void )
{
  int len = 0;
  char *str;

  printf("Please enter a string: ");
  str = malloc(MAX_STR_SIZE);     /* (1) */

  while( 1 )
  {
    size_t newline_pos;
    
    fgets( str, MAX_STR_SIZE, stdin );
    /* (2) */

    if( len == 0) /* (3) */
    {
      puts("You entered the following string: ");
    }

    newline_pos = strcspn(str, "\n" );

    str[newline_pos] = '[=11=]';
    len += strlen(str);   /* (4) */  
    fputs(str, stdout);

    if(newline_pos < MAX_STR_SIZE-1) /* (5) */
      break;
  }

  printf("\n\nCurrent size for string block: %d", len);

  free( str ); /* (6) */
  return 0;
}

所以,基本上,我只是使用 fgetsstdin 读取,迭代直到找到 '\n' 字符。为了了解是否满足此条件,我使用 strcspn() 函数,并使用相同的函数从结果字符串中删除换行符。

几个notes/assumptions(查看代码部分对应的数字):

  1. 只有在使用 C++ 编译器进行编译时才需要转换 malloc 的结果。 C
  2. 中可以省略
  3. 删除了fgets错误检查:它return在错误的情况下为NULL(在找到EOF之前没有读取任何字符。从标准输入读取它不会发生)
  4. 检查 len==0 我们确保 "You entered the following string: " 只打印一次
  5. 字符串的长度是对每次迭代读取的字符串长度求和得到的
  6. 当字符串包含'\n'时,满足break条件。否则 strcspn 的 return 值将是 MAX_STR_SIZE
  7. 即使OS会释放程序使用的所有动态内存,在return上,总是free总是
  8. 是个好习惯