0
char *file1charbuf=(char*)malloc(sizeof(char));
char *file2charbuf=(char*)malloc(sizeof(char));

in loop until EOF I read char into *file1charbuf and *file2charbuf and then compare.

...
check=read(file1, file1charbuf, 1);
check2=read(file2, file2charbuf, 1);
if (*file1charbuf!=*file2charbuf){
         printf("differ: char %i, line %i\n",charpos,linepos);
         exit(1);
}
....

compare works fine but i want to keep pointer in stack,not in heap. Also malloc is C lib function.

char *file1charbuf[1]; //1 element array of char
char *file2charbuf[1];

with that comparing doesnt work right

...
if (file1charbuf[0]!=file2charbuf[0]){
         printf("differ: char %i, line %i\n",charpos,linepos);
         exit(1);
}
...

and the second question. Is it necessary close(file1) if exit(1) found?

  • I should use ONLY sys calls,not lib functions.
Alexey
  • 221
  • 5
  • 12
  • @H2CO3: It has C++ and C tags, so obviously it should "work for both"? – Mats Petersson Apr 20 '13 at 11:17
  • @MatsPetersson I'm afraid so. (But again: who is compiling C code with a C++ compiler *on Unix?* And anyways it's ugly even when it's necessary and/or correct.) –  Apr 20 '13 at 11:18
  • you should use close to close the file descriptor. Its good practice to release the resource after use. In unix after exit all the resource will be reclaimed but for any OS (like Vxwokrs) which do not support resource reclamation will an issue. – Sumit Kumar Apr 20 '13 at 11:27
  • System calls *are* library functions... It seems like your professor has neglected a basic fundamental in his/her teachings: *types*. It might be a good idea to seek a different avenue of education, such as a book written by a *notable* professor... – autistic Apr 20 '13 at 11:55
  • "i want to keep pointer in stack,not in heap". By having `char *file1charbuf` the pointer is kept in stack. `char *file1charbuf[1];` this is an array of pointers to memory of type char which actually point to nothing - it's not an 1 element array of char. That would have been `char file1charbuf[1];` – Lefteris E Apr 21 '13 at 10:36

5 Answers5

5

There's quite a few issues with the code you're showing, I'm afraid:

  1. Don't cast the return value of malloc(), in C.
  2. sizeof (char) is always 1 in C, so it's quite pointless to use it like this.
  3. You're declaring arrays of pointers to characters, when you seem to mean arrays of characters.

    char *file1charbuf[1]; //1 element array of char should be
    char file1charbuf[1]; /* 1-element array of char */ or, of course, just
    char file1charbuf; /* 1-character buffer. */

  4. You're doing read() with 1-byte buffers, which is fantastically inefficient.

  5. To compare character arrays (not necessarily strings, i.e. doesn't have to be zero-terminated) with more than 1 character, use memcmp().
  6. It's best to call close() on all open file descriptors before calling exit(). On most operating systems, the death of the process will lead to all its resources being re-claimed, but it's better to do it explicitly. If the file I/O was using the buffered FILE*-based calls, there would be no need since those are closed by exit() automatically in all environments.
Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • Oh, so you let the file descriptor leak? What do you say when you have code auditors looking for memory leaks and giving you a hard time because you're letting file descriptors leak? *"It's cleaner, but not necessary"*? What does your boss say for making the job harder for everyone else? *"You're fired"*? Yes... – autistic Apr 20 '13 at 11:48
  • FWIW, I once worked with a TI DSP where the C compiler had a `sizeof(char) == 2`. I think C asks for minimums, but I don't believe it states that `sizeof(char)` *must* be 1. IIRC, it was a C89-based compiler. – John Szakmeister Apr 20 '13 at 11:54
  • 3
    @jszakmeister That compiler wasn't a C compiler. In C, `sizeof (char)` is **always** one. `CHAR_BIT` might vary from system to system, but the `sizeof` operator returns the number of `char`s in a type or the type of an expression. How many `char`s are in a `char`? – autistic Apr 20 '13 at 11:57
  • Can you cite where that is in the language spec? It was early days, so it may very well have been implemented poorly. :-) – John Szakmeister Apr 20 '13 at 11:58
  • 6.5.3.4 states "*The sizeof operator yields the size (in bytes) of its operand*". – John Szakmeister Apr 20 '13 at 12:00
  • 1
    @jszakmeister 6.5.3.4p4: *When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.* – autistic Apr 20 '13 at 12:01
  • Yep, just saw it now. Thanks. – John Szakmeister Apr 20 '13 at 12:02
  • @modifiablelvalue Okay, I re-worded it to be less forgiving. I might have been thinking of `FILE*` I/O when I wrote the original answer, thanks for pointing that out. – unwind Apr 20 '13 at 12:14
0

char *file1charbuf[1]; is an array of one pointer to a char. If you want an array of one char, use char file1charbuf[1].

James M
  • 18,506
  • 3
  • 48
  • 56
0

The definitions are not pointers to char arrays, they are char arrays.

char file1charbuf[1]; //1 element array of char
char file2charbuf[1];

There is no difference in comparision semantics of strings using memory allocated on the heap and that of memory allocated on the stack.

suspectus
  • 16,548
  • 8
  • 49
  • 57
0
...
char c1, c2;
check=read(file1, &c1, 1);
check2=read(file2, &c2, 1);
if (c1!=c2) {
...
Leonid Volnitsky
  • 8,854
  • 5
  • 38
  • 53
0

Code to compare 2 files and list the line and character that differ. It doesn't compare them line-by-line rather character by character, but keeps track of the line number and loads the file into blocks of 4Kbytes.

#define BLOCKSIZE 4096

char file1charbuf[BLOCKSIZE]; //4096 character buffer in stack
char file2charbuf[BLOCKSIZE];
int linepos=1, charpos =1, i, b1, b2 ;
int file1 = open("1.txt", O_RDONLY);
int file2 = open("2.txt", O_RDONLY);

do{
   b1=read(file1, file1charbuf, BLOCKSIZE);
   b2=read(file2, file2charbuf, BLOCKSIZE);
   for(i=0; i < b1 && i < b2; ++i){
      if (file1charbuf[i]!=file2charbuf[i]){
         printf("differ: char %i, line %i\n",charpos,linepos);
         close(file1);
         close(file2);
         exit(1);
      }
      if (file1charbuf[i] == '\n'){
         ++linepos;
         charpos=0;
      }
      ++charpos;
   }
}while(   (b1 == BLOCKSIZE || (file1==STDIN && file1charbuf[b1-1] != 0x26)) 
       && (b2 == BLOCKSIZE || (file2==STDIN && file2charbuf[b2-1] != 0x26)) );

if (b1 != b2)
   printf("One bigger than the other\n");
close(file1);
close(file2);

About reading from STDIN:

read() from stdin unblocks when you press enter. At that time only the characters you typed so far are availiable to be read. This means that b1 will equal to the characters you typed so far. The do-while condition will fail because read didn't read all the 4096 bytes it requested, which will make it think that it's because the stream has ended. To continue reading after the \n we have to change the while condition so that if the file descriptor we are reading is STDIN, to continue reading unless the last character we read is the stream end character which i think is 0x26. I hope that ^D will also unblock read() in the same way enter does.

Lefteris E
  • 2,806
  • 1
  • 24
  • 23
  • if file1 is "abc" file2 is "ab" your programm return equal – Alexey Apr 21 '13 at 12:24
  • indeed, need to put an `if (b1!=b2) printf("one bigger than the other\n");` – Lefteris E Apr 21 '13 at 12:40
  • ,Thanks! And last question. If file1 or file2 equal 0(STDIN), if I push enter it will be \n and will stop,but why? how to continue after \n and reading until ^D(unix stream end)? – Alexey Apr 21 '13 at 13:34