简体   繁体   English

C 从标准输入读取行

[英]C reading lines from stdin

My goal is to read every line from a piped.txt file with the getline() function, but I somehow get a error every time I use this function:我的目标是使用 getline() function 从 piped.txt 文件中读取每一行,但每次使用此 function 时都会出现错误:

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

I always get the errorcode: [Error] Id retruned 1 exit status我总是收到错误代码:[Error] Id reruned 1 exit status

I've reproduced the linking error on DevC++ , in which getline() seems to be missing even after forcing recent C revisions with gcc compiler options such as -std=c11 .我已经重现了DevC++上的链接错误,即使在使用gcc编译器选项(例如-std=c11 )强制最近的 C 修订后, getline()似乎也丢失了。

So I've rewritten your code using fgets() :所以我用fgets()重写了你的代码:

char *fgets(char *s, int size, FILE *stream);

It is for sure more portable than getline but has a few differences:它肯定比getline更便携,但有一些区别:

  • It reads up to size-1 characters if the newline is not encountered before this limit (it automatically appends the string terminator).如果在此限制之前没有遇到换行符,它最多读取size-1字符(它会自动附加字符串终止符)。 So it doesn't manage buffer reallocation所以它不管理缓冲区重新分配
  • The resulting string contains the '\n' character, if found结果字符串包含'\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] = '\0';
    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;
}

So, basically, I just use fgets to read from stdin , iterating until the '\n' character is found.所以,基本上,我只是使用fgetsstdin读取,迭代直到找到'\n'字符。 In order to understand is this condition is met, I use strcspn() function, and I use the same function to remove the newline from the resulting string.为了了解是否满足此条件,我使用strcspn() function,并使用相同的 function 从结果字符串中删除换行符。

A few notes/assumptions (check the corresponding number in code section):一些注释/假设(检查代码部分中的相应数字):

  1. Casting the result of malloc is required only if you are compiling with a C++ compiler.仅当您使用 C++ 编译器进行编译时,才需要malloc的结果。 It can be omitted in C C中可以省略
  2. Removed fgets error check: it returns NULL in case of error (no chars read before EOF is found. It won't happen reading from stdin)删除了fgets错误检查:它返回 NULL 以防出错(在找到 EOF 之前没有读取字符。它不会从标准输入读取)
  3. Checking for len==0 we make sure that the "You entered the following string: " is printed only once检查len==0我们确保"You entered the following string: "仅打印一次
  4. The length of the string is calculated by summing the length of the strings read in every iteration字符串的长度是通过将每次迭代中读取的字符串的长度相加来计算的
  5. The break condition is met when the string contains '\n' .当字符串包含'\n'时满足break条件。 Otherwise strcspn 's return value will be MAX_STR_SIZE否则strcspn的返回值为MAX_STR_SIZE
  6. Even if the OS will release all the dynamic memory used by the program, on return, it is a good habit always free ing it anyway即使操作系统将释放程序使用的所有动态 memory,在返回时,始终free它是一个好习惯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM