Lab 1: C for C++ programmers

  1. Use printf() instead of cout and fprintf(stderr, "...") instead of cerr. eg:
    #include <stdio.h>
    
    int main(void) {
        int i = 123;
        float f = 1 / 3.0;
        double d = 1 / 3.0;
        char *str = "Hello World!";
    
        printf("i = %d, f = %.20f, d = %.20f\n"
    	   "str = %s, partial_str = %.5s\n",
    	   i, f, d, str, str);
    
       /*
        * Result:
        * i = 123, f = 0.33333334326744079590, d = 0.33333333333333331483
        * str = Hello World!, partial_str = Hello
        */
    
       return (0);
    }
        
  2. Use scanf() instead of cin. eg:
    #include <stdio.h>
    
    int main(void) {
        double x, y;
    
        scanf("%lf %lf", &x, &y);
        printf("x = %f, y = %f\n", x, y);
    
        return (0);
    }
    
    Another example:
    ----------------
    #include <stdio.h>
    
    int main(void) {
        char name[32];
    
        printf("What's your name? ");
        scanf("%31[^\n]", name);
        printf("Hello, %s\n", name);
    
        return (0);
    }
        
  3. Use struct instead of class. eg:
    #include <stdio.h>
    
    typedef struct {
        int x, y;
    } point_t;
    
    int main(void) {
        point_t point;
        point.x = 10;
        point.y = 20;
    
        printf("x = %d, y = %d\n", point.x, point.y);
    
        /*
         * Result:
         * x = 10, y = 20
         */
    
        return (0);
    }
        
  4. Use pointer instead of reference. eg.
    #include <stdio.h>
    
    void func(int *x) {
        *x = 10;
    }
    
    int main(void) {
        int x = 0;
    
        printf("Before, x = %d\n", x);
        func(&x);
        printf("After, x = %d\n", x);
    
        /*
         * Result:
         * Before, x = 0
         * After, x = 10
         */
    
        return (0);
    }
    
  5. Use malloc() and free() instead of new and delete. eg:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define N    100
    
    typedef struct {
        int x, y;
    } point_t;
    
    int main(void) {
        point_t *points = (point_t *)malloc(sizeof(point_t) * N);
    
        int i;
        for (i = 0; i < N; i++) {
    	points[i].x = points[i].y = 0;
        }
    
        /* Or, we can do: memset(points, 0, sizeof(point_t) * N); */
    
        /* Blah blah blah */
    
        free(points);
    
        return (0);
    }
        
  6. Use open(), close(), read(), write(), lseek() instead of fstream. eg:
    #include <stdio.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <unistd.h>
    #include <string.h>
    
    #define PASSWD_FILE    "/etc/passwd"
    
    int main(void) {
        char buf[256];
        int byte_read = 0;
        int fd = open(PASSWD_FILE, O_RDONLY);
    
        if (fd < 0) {
    	fprintf(stderr,
    		"Failed to open %s: %s\n", PASSWD_FILE, strerror(errno));
    	return (1);
        }
    
        while ((byte_read = read(fd, buf, sizeof(buf))) > 0) {
    	printf("%.*s", byte_read, buf);
        }
    
        do {
    	/* Go to beginning of the file */
    	if (lseek(fd, 0, SEEK_SET) < 0) {
    	    fprintf(stderr, "Failed to call lseek(): %s\n", strerror(errno));
    	    break;
    	}
    
    	/* Advance 10 bytes from current offset */
    	if (lseek(fd, 10, SEEK_CUR) < 0) {
    	    fprintf(stderr, "Failed to call lseek(): %s\n", strerror(errno));
    	    break;
    	}
    
    	/* Go to the end of the file */
    	if (lseek(fd, 0, SEEK_END) < 0) {	
    	    fprintf(stderr, "Failed to call lseek(): %s\n", strerror(errno));
    	    break;
    	}
    
    	/* Go to 16 bytes from the end of the file */
    	if (lseek(fd, -16, SEEK_END) < 0) {
    	    fprintf(stderr, "Failed to call lseek(): %s\n", strerror(errno));
    	    break;
    	}
        } while (0);
    
        if (close(fd) < 0) {
    	fprintf(stderr,
    		"Failed to close %s: %s\n", PASSWD_FILE, strerror(errno));
        }
    
        return (0);
    }
        
  7. Man page is your friend. eg:
    % man 2 mkdir
      eg. mkdir("foo", 0644) will create a directory named "foo" with permission -rw-r--r--
    % man 2 chdir
      eg. chdir("foo") will change current directory to "foo"
    % man 2 open
      eg. open("bar", O_CREAT | O_WRONLY) will create a file named "bar" for writing
    % man 2 write
      eg. write(fd, "Hello World!\n", 13) will write "Hello World!\n" into a file referenced by the file descriptor fd 
    % man 2 chmod
      eg. chmod("foo", 0600) will change permission of "foo" to -rw-------
    % man 2 access
      eg. access("foo", R_OK) will check if "foo" is readable
        
  8. Compile with "-W -Wall -Werror -pedantic" to receive full credit.
  9. It is always a good practice to check the return values of system/function calls.