0

The program reads lines from the standard input. Each line is printed on the standard output preceded by its line number. The program has no built in limit on how long a line it can handle.

my answer is:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 30

int main(){  

int line_n=0;
char line[MAXSIZE];
char *p;

while(gets(&line))
{ 
  if('\n'){
    if(*line=='q') break;
    else if(strlen(line)>MAXSIZE){
    p=&line;
    p=(char *)malloc(sizeof(strlen(line))); //failed to use dynamic memory allocation here
        printf("%d).",line_n);
        printf("%s\n",line);
      }
   else{
  printf("%d).",line_n);
  printf("%s\n",line);
    }
 }
  line_n++;
}

I am pretty new to C programming and I need help with this dynamic memory allocation. I have overflows when my input is bigger than MAXSIZE.

Mor Haham
  • 65
  • 7
  • 1
    Can you use [`getline`](http://man7.org/linux/man-pages/man3/getline.3.html)? It will do all the tedious work for you. – 5gon12eder Oct 11 '14 at 00:21
  • http://stackoverflow.com/questions/4346598/gets-function-in-c never use gets – pm100 Oct 11 '14 at 00:24
  • its also not clear what you have in mind. Are you trying to store all the lines in memory or just create a buffer big enough for the largest one – pm100 Oct 11 '14 at 00:25
  • I don't care about loosing lines, I want to make a buffer big enough to print the unlimited line of strings and free the memory. – Mor Haham Oct 11 '14 at 00:28
  • with gets(&line) you are already dead, doesn't matter what you do after. If the line is bigger than MAXSIZE you have already invoked undefined behavior. Use getline – pm100 Oct 11 '14 at 00:30
  • OK,thank you. It will be fantastic if I could get a full answer. how to use getline and what to do with the memory allocation. – Mor Haham Oct 11 '14 at 00:34

2 Answers2

1

Try this:

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

#define ALLOCSIZE 30

int main()
{  
    int line_n = 0;
    char *line = NULL;
    int linelen = 0;
    int linecap = 0;
    char *p;
    int c;

    while ((c = fgetc(stdin)) != EOF)
    {
        if (c == '\n')
        {
            if ((line) && (*line == 'q'))
            {
                linelen = 0;
                break;
            }

            printf("%d).%.*s\n", line_n, linelen, line);
            linelen = 0;
            line_n++;
        }
        else
        {
            if (linelen == linecap)
            {
                p = (char *) realloc(line, linecap + ALLOCSIZE);
                if (!p) break;
                line = p;
                linecap += ALLOCSIZE;
            }

            line[linelen] = c;
            linelen++;
        }
    }

    if (linelen > 0)
        printf("%d).%.*s\n", line_n, linelen, line);

    free(line);

Or this:

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

int main()
{  
    int line_n = 0;
    char *line = NULL;
    size_t linelen = 0;
    char *p;

    while (getline(&line, &linelen, stdin) != -1)
    { 
        if (*line == 'q') break;
        printf("%d).%.*s\n", line_n, linelen, line);
        line_n++;
    }

    free(line);
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

If you dont wnat to use getline - ie you want to do the heavy lifting as an excercise then you have to do this

make a buffer (say 50 chars) with malloc
loop
   get 1 char
   end of line? -> done
   buffer full ?
      use realloc to make bigger buffer
   put 1 char in buffer
pm100
  • 48,078
  • 23
  • 82
  • 145
  • Why I need to use malloc at the beginning if I still don't know If I will need it later or not?It's like using memory for nothing, no? – Mor Haham Oct 11 '14 at 00:38
  • You don't have to, you can allocate it the first time you need to insert a character into it. – Remy Lebeau Oct 11 '14 at 00:46
  • This is basically how `vector` in c++ works. You could only give yourself one more character each time you read a new character, but by doing it in chunks you get better performance, of course at the cost of possibly wasting some memory. – IllusiveBrian Oct 11 '14 at 00:46
  • `vector` allocates its internal memory in chunks. When you insert the first element, it allocates more room than just for one element, (unless you preallocate the `vector` and don't exceed the capacity on the first element). – Remy Lebeau Oct 11 '14 at 00:52