0

I am trying to read a file and then read each character until i reach a new line the do some work on that line. Here is what i have done so far:

  char line[] = "";
  char *charcter = "";

  //If i do this here it works fine, but below it's not working at all
  charcter = "asssss";
  strcat(line,charcter);

  //Read file
  inputFile = fopen(fileName,"r");
  if (inputFile) 
  {
    while ((charcter = (char)getc(inputFile)) != EOF)
           strcat(line,charcter); //This piece code keeps crashing my program on run

    fclose(inputFile);
  }

I am a C# developer and i am really frustrated that i can't figure out this thing, please help.

Edit:

I have modified the piece line and allocated memory to it like this:

char *line = (char*)malloc( 400 *sizeof(char));

now the strcat in the while loop works but crashes after taking all the values (the input is much smaller than the allocated memory), and if i put the same strcat statment inside an if statment it will take the first letter then crash.

So what is the problem here ?

ykh
  • 1,775
  • 3
  • 31
  • 57

2 Answers2

2

You're trying to modify a string in an array on the the stack. You allocate line[] as "" (i.e. one byte, the null character) and then try to scribble over the memory with strcat (which will modify the memory pointed to by its first argument).

When you put a string into the text of your source and assign it to an array variable in a function, that much memory is allocated on your stack in the function's call-frame. If you access memory after it, you're scribbling over other bits of your stack, which can modify not only the data but the behaviour of your program.

It's like creating a fixed array in C# and then trying to append to it. The language won't let you do it, because that would involve writing over any other memory that happens after the end of the array. C will let you try, but then crash because you're scribbling over memory you don't own, or worse, let you do it and then continue running in an unknown state. Who knows what else is found a few bytes along from the address of line? You don't.

See this question for more info: String literals: Where do they go?

Once you have a pointer to a memory address, C only knows that it's a pointer. It doesn't know what kind of memory it points to (static constants, stack, heap), so it will let you make this mistake. When you do make the mistake, the operating system might say "actually no, that's not allowed" by raising a segmentation fault, or it might not if it's a more subtle bug.

You should allocate a big buffer with malloc, enough to fit the file (dangerous) or re-allocate the buffer to expand it each time.

EDIT I realised that line is a char[] not a char*, so edited my answer.

Community
  • 1
  • 1
Joe
  • 46,419
  • 33
  • 155
  • 245
  • Please don't call it `NULL` character. As `NULL` is a correctly not a token, it is a address constant. and `""`does also not "allocate something", AFAIK. – dhein Sep 26 '13 at 13:43
  • Surely `""` is allocating an empty string in the program text at compile time? Perhaps we misunderstood each other, I'm talking about a null character (`'\0'`) not a `NULL` memory address. The difference between `""` and `0x0` or `'\0'` is that the first is a pointer to an empty one-byte null string, the second is a zero value. – Joe Sep 26 '13 at 13:46
  • But isn't this jsut called "zero token" or "zero terminator"? Why you call it null char then? "It doesn't know what kind of memory it points to" This is by the way also not correct, as C provides of aliasing rules, where it is pretty important what kind of type a aligned memory block has ;) – dhein Sep 26 '13 at 13:50
  • I called it the null character because that's what it's called in the character set. See here: http://en.wikipedia.org/wiki/Null_character – Joe Sep 26 '13 at 13:52
  • 1
    Yes, C knows the type of the pointer but not whether it points to constant program text or to the stack or the heap. – Joe Sep 26 '13 at 13:52
  • I said the kind of memory not what you are storing in it (which is where the aliasing is relevant). – Joe Sep 26 '13 at 13:53
  • "the stack or the heap" I like you mentioned this! – dhein Sep 26 '13 at 13:53
  • @Zaibis The C spec says "A byte with all bits set to 0, called the _null character_ ..." (C11 5.2.1 2). But I am with you on against using uppercase NULL in describing that byte. – chux - Reinstate Monica Sep 26 '13 at 16:58
  • I didn't uppercase it! – Joe Sep 26 '13 at 17:40
  • @Joe No one said you did ;) he just said he is also against it :D well so thanks for improoving my knowledge you 2! – dhein Sep 26 '13 at 17:55
2
  • You cannot strcat() a character - you need a string
  • The type of character variable should be int (check the prototype for getc())
  • If you still want to do it character by character, consider adding it to a string by index (and NUL-terminate at the end)
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Alexander L. Belikoff
  • 5,698
  • 1
  • 25
  • 31