2
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/types.h>
int main()
{
  int n,i=0;
  int f1,f2;
  char c,strin[100];
  f1=open("data",O_RDWR|O_CREAT|O_TRUNC);

  while((c=getchar())!='\n')
  {
    strin[i++]=c;
  }
  strin[i]='\0';
  write(f1,strin,i);
  close(f1);

  f2=open("data",O_RDONLY);
  read(f2,strin,0);
  printf("\n%s\n",strin);
  close(f2);
  return 0;
}

this code works perfectly fine on some machines while it prints out garbage on others, how to make it run correctly on all machines ?

Arun A S
  • 6,421
  • 4
  • 29
  • 43
Aly Omar
  • 41
  • 1
  • 2
  • 1
    please check the return value of `open()` for success first. – Sourav Ghosh Apr 21 '15 at 15:41
  • even if I omit the file access part i.e., just filling the string then printing it again, I still get the same results – Aly Omar Apr 21 '15 at 15:45
  • did you try with formatted i/o? – Sourav Ghosh Apr 21 '15 at 15:46
  • The "man -S2 read" says: DESCRIPTION read() attempts to read up to count bytes from file descriptor fd into the buffer starting at buf. If count is zero, read() returns zero and has no other results. If count is greater than SSIZE_MAX, the result is unspecified., but I tried this code and read(), also with count==0, returns the number of read byte!!! – Sir Jo Black Apr 21 '15 at 16:30
  • I signal you that the strange case I indicate above is due to the fact that I've not cleaned the buffer! – Sir Jo Black Apr 21 '15 at 17:32
  • On my PC with Linux there's another problem in you code! It doesn't set the permission and then there're problem in managing the file! ... To skip these problems you have to use f1=open("data",O_RDWR|O_CREAT|O_TRUNC, 0666); (see about the mode field) – Sir Jo Black Apr 21 '15 at 17:37

3 Answers3

2

Your call to read() is not actually reading anything. The third argument is the maximum number of bytes to read, and you're passing it 0:

read(f2,strin,0);

You need to pass it the size of your buffer instead, minus one to accommodate a terminating nul byte:

int bytesread = read(f2,strin,99);  /* since your buffer is size 100 */
strin[bytesread] = '\0';

The only reason this is ever working is because you don't clear strin between the first time you fill it via getchar() and the second time when you read() into it. So when you see data, it is leftover data from the first time. If you add a:

memset(strin, 0, 100);

to your original code before the read(), you will see that it never prints the data on any machine.

Moldova
  • 1,641
  • 10
  • 13
  • The strange is that on my ubuntu the function read() reads also with count==0 ... I read the man that says that with counter 0 read() does nothing!!! But I've tried to use read as in the code above and it reads! – Sir Jo Black Apr 21 '15 at 17:13
  • 1
    Are you sure? Try wiping the buffer with memset before the read() and see what it looks like. When I do that it becomes clear that the read() did nothing. If you don't erase strin first though you may see its previous contents and be fooled into thinking that it was read() that put it there. – Moldova Apr 21 '15 at 17:15
  • I've tried as you say! don't cleaning the buffer was my error! – Sir Jo Black Apr 21 '15 at 17:31
  • you are perfectly right on that point ....however the problem is I've tried to omit all file access functions i.e. just filling the string and printing it again as it is ....and still printing garbage on some machines – Aly Omar Apr 21 '15 at 18:43
  • Can you share the code with the file access functions removed so we can see exactly what you're doing? – Moldova Apr 21 '15 at 19:06
0

I think this problem is a simple one and that when you use getchar() to get characters till '\n' you are in fact not accounting for Windows carriage return being \r\n while it is \n in Unix You will get details in the link below

Does Windows carriage return \r\n consist of two characters or one character?

P.S. I am a newbee here so i apologize before hand if this answer isn't what you were looking for.

Community
  • 1
  • 1
Phoenix
  • 1
  • 1
0

The code that you wrote doesn't work fine! The problem is simple! Or you write and then you read also the \x0 at the end of the string or, when you read, you add the \x0 to the end of the read string! :)

Save also the \x0

write(f1,strin,i+1);

Read and add the \x0

i=read(f2,strin,sizeof(strin)-1);
strin[i]=0;

I think the best solution is the second one!;)

Sir Jo Black
  • 2,024
  • 2
  • 15
  • 22