K.W.
K.W.

Reputation: 59

read() function error in C

I'm trying to read from .txt file until I hit the character "=". Text file is always the same,contains only these strings:

TaskLimit=3
cc pr.c && ./a.out

Sometimes the code works fine and quits the while loop and sometimes it prints "TaskLimit" but then throws "Segmentation fault (core dumped)" error. Any ideas what am I doing wrong? Should I clear the buf[] or something?

   char buf[1];

   file = open(argv[1], O_RDONLY);
   if (file == -1){
      perror("Error opening file");
      exit(1);
   }
   while(1){
       read(file, buf, 1);
       if(buf[0]=='=') {printf("I'm out");break;}
       printf("%c",buf[0]);

   //further actions

edit: in the "further actions" I'm trying to convert a char to int and this seems to be the problem:

char limit_char[0];
int limit;
read(file,limit_char,1);
limit=atoi(limit_char[0]);

edit2: changing this line

limit=atoi(limit_char[0]);

to

limit=atoi(&limit_char);

helped.

Upvotes: 0

Views: 3960

Answers (4)

silen
silen

Reputation: 534

The most important part of C programming is checking return values.

In your sample code sample you do it for open(2), but not for read(2) and you should, because not only does it tell if there was an error, it also tells how many bytes have been read. Excerpt from the man page:

   On success, the number of bytes read is returned (*zero indicates end of file*),
   and the file position is advanced by this number.

That is, knowing that there is nothing more to read - return value of zero - can let you break from the loop in case the user gave you an invalid file.

When you learn C, I suggest (and pretty much every person on this site) to always compile with -Wall -Wextra -Werror. C is a spartan language and mastering it requires discipline. GCC (or whatever your compiler is) would never have let you execute:

limit=atoi(&limit_char);

As the type of &limit_char is effectively char ** and atoi expects a const char *.

Upvotes: 3

Chris Turner
Chris Turner

Reputation: 8142

atoi requires a NULL-terminated array of char so your array needs 1 more element than you're reading in.

char limit_char[2];
int limit;
read(file,limit_char,1);
limit_char[1]='\0';
limit=atoi(limit_char);

beyond that, you should probably be checking the return value from read to make sure you've actually read something in.

Upvotes: 2

Jabberwocky
Jabberwocky

Reputation: 50775

This declaras an array of length zero which doesn't make much sense. BTW: normally the compiler should emit at least a warning.

char limit_char[0];

this wont work, you need an array of length 1 because you read 1 byte with read:

char limit_char[1];

or rather this:

char limit_char;
...
read(file, &limit_char, 1);

Upvotes: 0

Marc Balmer
Marc Balmer

Reputation: 1830

  1. In your code, your refer to argv[1] for the filename, but on the example usage (cc pr.c && ./a.out) you don't specify any filename.

  2. In you read() statement you use a variable plik which is not defined anywhere, use file here, i.e. the variable you used to store the result of `open().

Fix this and it will work.

Upvotes: 1

Related Questions