简体   繁体   中英

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:

#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

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 .

So I've rewritten your code using fgets() :

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

It is for sure more portable than getline but has a few differences:

  • It reads up to size-1 characters if the newline is not encountered before this limit (it automatically appends the string terminator). So it doesn't manage buffer reallocation
  • The resulting string contains the '\n' character, if found
#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. 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.

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. It can be omitted in 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)
  3. Checking for len==0 we make sure that the "You entered the following string: " is printed only once
  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' . Otherwise strcspn 's return value will be 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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