0

One excercise commonly asked on my faculty's exams is using a function to load a text(<1000 characters) into an array that can include "enter" or "\n".

The way I've seen other people do it is the following:

char * load (int  *characters) //characters=amount of characters written
{    
    static char *text;
    *characters=0;
    while((*characters<999) && (((text[*characters]) = getchar()) != EOF))
    {
        ++*characters;
    }
    text[*characters]='\0';
    return(text);
}

My problem is that I always get segmentation violations when trying to input something. I'd love some help!

Mateusz Grzejek
  • 11,698
  • 3
  • 32
  • 49
  • 1
    `text` is NULL, so you're going to crash at `text[*characters]`. Also, comparing a `char` to `EOF` doesn't make sense. – melpomene Aug 19 '15 at 22:55
  • An easy way to think of it is, because `text` is nothing, when you ask for its location in memory with `text[*characters]` it crashes, because nothing has no address. – MeetTitan Aug 19 '15 at 23:07
  • Personally, when I want to read a block of a particular size, I just use read(). – Arlie Stephens Aug 20 '15 at 02:05

3 Answers3

2

Allocate some memory for text via malloc. E.g.,

char *text = malloc(1000);

And remember to free memory at the end of the function using free.

upd: Alternatively, you can consider using stack instead of heap:

static char text[1000];

Note that in both cases you should allocate maximum length plus one byte for string because of '\0' at the end.

nightuser
  • 664
  • 4
  • 13
  • Thanks. I tried this static char text[1000]; and it worked. –  Aug 19 '15 at 23:06
  • melpomene: well, you're right, in this case it's not needed as you have to `free` memory after all. – nightuser Aug 19 '15 at 23:12
  • 1
    A static array exists in what is usually called the data segment of a program, not from the stack or from the heap. _alloca() could be used to allocate from the stack (which auto frees when the function returns), but it's rarely used these days. – rcgldr Aug 20 '15 at 02:22
0

No need to pass an int pointer for characters. Also your whole array concept seems to be quite off. See here for ways to work with char arrays. You only declare a char pointer but you never point it to a memory block, which means that once you start traversing you go God knowns where and get segmentation violations.

  1. Declare an array on the stack or reserve dynamically memory and assign a pointer to that block
  2. Loop while getchar() isn't equal to \n or EOF (you can also use the ASCII code for the Enter, which, if I remember correctly, is the number 13). Also depending on the way you have declared your array you will have to put a counter for the index of the array cell currently being handled or just increase the pointer by one
  3. Insert the character received from getchar() in your array

Here is one more easy to follow tutorial that might help you get a hold on the pointer/array situation.

Community
  • 1
  • 1
rbaleksandar
  • 8,713
  • 7
  • 76
  • 161
0

A pointer is not an array.

So

static char *text;

defines a pointer which, since it is static is a NULL pointer. The next action is attempting to treat that pointer as if it is an array,

while((*characters<999)&&(((text[*characters])=getchar())!=EOF))

which gives undefined behaviour. Practically, the result is usually overwriting some random area of memory. Operating systems - if they detect that - will terminate your program (which, in your case, means by triggering a segmentation violation).

Making text static is irrelevant. Without the static keyword, all that happens is that text is created automatically when your program is run, and doesn't exist after it returns. In that case, it will be uninitiatialised (which means even accessing its value gives undefined behaviour).

What you need to do is make text point at a valid location in memory. Since you are returning its value, that value has to be valid after the function returns. One way is

 char text = malloc(999 + 1);

which will be fine, as long as the input does not exceed 999 characters. It will also be necessary for the caller to release that memory to avoid a memory leak.

Also, getchar() returns an int. An int can represent the value of EOF. There is no guarantee that a char can. So assigning (text[*characters])=getchar() means that value (since it has been converted to be a char) may never compare equal with EOF.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • You should allocate one extra byte for '\0' at the end of the string. – nightuser Aug 19 '15 at 23:30
  • Detail: a `char` and `int` _can_ both have the value of `EOF`. Example: signed `char` and `EOF == -1`. The problem is that `char` cannot distinctly hold all the different values return from `getchar()`. `0` to `UCHAR_MAX` and `EOF`: typically 257 different values. – chux - Reinstate Monica Aug 20 '15 at 03:42