#include <stdio.h> // for printf(), putchar()
int main (int argc, char* argv[])
{
printf ("The name of this program is \"%s\"\n", argv[0]);
printf ("This program was invoked with %d argument", argc - 1);
if (argc != 2) {printf("s\n");}
else {putchar('\n');}
// Were any command-line arguments specified?
if (argc > 1) // Yes, print them
{
int i;
if (argc != 2) {printf ("The arguments are:");}
else {printf ("The argument is:");}
for (i = 1; i < argc - 1; i++) // skip program name, argv[0]
{printf (" %s", argv[i]);}
printf (" %s\n", argv[i]);
}
return 0;
}
/*
gcc arglist.c -o arglist
./arglist
The name of this program is "./arglist"
This program was invoked with 0 arguments
./arglist Hello
The name of this program is "./arglist"
This program was invoked with 1 argument
The argument is: Hello
./arglist Hello, world!
The name of this program is "./arglist"
This program was invoked with 2 arguments
The arguments are: Hello, world!
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <getopt.h> // for struct option, optarg, optind, getopt_long()
#include <stdio.h> // for printf(), fprintf(), stdout, stderr, NULL,
// getchar(), EOF, FILE, fopen(), fputc(), fclose()
#include <stdlib.h> // for exit(), abort()
const char* prog; // program name, argv[0]
void print_usage (FILE* stream, int exit_code);
int main (int argc, char* argv[])
{
prog = argv[0]; // program name
if (argc == 1)
{print_usage (stdout, 0);} // exit code 0 (normal termination)
int next_option; // return value of getopt_long()
const char* const short_options = "ho:v";
const struct option long_options[] =
{
{ "help", 0, NULL, 'h' }, // no arguments
{ "output", 1, NULL, 'o' }, // one arg, a file name
{ "verbose", 0, NULL, 'v' }, // no arg
{ NULL, 0, NULL, 0 } // Required at end of array
};
const char* out = NULL; //output filename, NULL for stdout
int verbose = 0; // Whether to display verbose messages
do
{
next_option = getopt_long (argc, argv, short_options,
long_options, NULL);
switch (next_option)
{
case 'h': // -h or --help
print_usage (stdout, 0); // exit code 0 (normal termination)
case 'o': // -o or --output
out = optarg; // output filename
break;
case 'v': // -v or --verbose
verbose = 1;
break;
case '?': // user specified an invalid option
print_usage (stderr, 1); // exit code 1 (abnormal termination)
case -1: // no more options are found
break;
default: // Something else, unexpected
abort (); // end program abruptly (do not flush streams
} // or close open files)
} while (next_option != -1); // Done with options
if (verbose) // print arguments following options
{ // `optind' points to first nonoption argument:
int i;
for (i = optind; i < argc; i++)
{printf ("Argument: %s\n", argv[i]);}
}
FILE *fp = NULL;
if (out != NULL)
{fp = fopen(out, "w");} // open for writing
if (fp == NULL) // if no out file or error opening file
{fp = stdout;}
int c;
while ((c = getchar()) != EOF)
{fputc(c, fp);}
if (fp != NULL)
{fclose(fp);}
return 0;
} // return from main() flushes streams and closes open files
void print_usage (FILE* stream, int exit_code)
{ // `stream' is typically `stdout' or `stderr'
fprintf (stream, "Usage: %s options [inputfile ...]\n", prog);
fprintf (stream, " -h --help Display this usage information\n"
" -o --output filename Write output to file\n"
" -v --verbose Print verbose messages\n"); // concatenate strings
exit (exit_code); // end program with `exit_code'
} // exit() flushes streams and closes open files
/*
gcc getopt_long.c -o getopt_long
./getopt_long
Usage: ./getopt_long options [inputfile ...]
-h --help Display this usage information
-o --output filename Write output to file
-v --verbose Print verbose messages
./getopt_long -hh --help
Usage: ...
./getopt_long -?
./getopt_long: invalid option -- '?'
Usage: ...
./getopt_long --?
./getopt_long: unrecognized option '--?'
Usage: ...
./getopt_long -v
Hello!
Hello!
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
./getopt_long -hov out.txt // no file is created
Usage: ...
./getopt_long -ov out.txt // file `v' is created
Hello!
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
// `v' contains "Hello!"
// no verbose messages are printed
rm v // delete file `v'
./getopt_long -v -o out.txt // file `out.txt' is created
Hello! // Enter
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
// `out.txt' contains "Hello!"
// no verbose messages are printed
./getopt_long -v -o out.txt Hello!
Argument: Hello!
How are you today? // Enter
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
// `out.txt' contains "How are you today?"
./getopt_long Hello! -o out.txt "What's" -v up?
Argument: Hello!
Argument: What's // ' is interpreted by the shell, so we write "What's"
Argument: up?
Have a nice day! // Enter
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)
// `out.txt' contains "Have a nice day!"
rm out.txt // clean
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // for putchar(), printf(), fprintf(),
// stdout, stderr, fflush()
#include <unistd.h> // for sleep()
int main()
{
int i;
for (i = 0; i < 5; i++)
{
printf ("."); // print to stdout (buffered)
sleep (1);
}
putchar('\n');
for (i = 0; i < 5; i++)
{
printf ("."); // print to stdout (buffered)
sleep (1);
fflush(stdout); // empty buffer
}
sleep (1);
putchar('\n');
for (i = 0; i < 5; i++)
{
fprintf (stderr, "."); // print to stderr (unbuffered)
sleep (1);
}
putchar('\n');
return 0;
}
/*
gcc buffering.c -o buffering
./buffering
..... // wait 5 seconds before all 5 dots are printed
..... // print 1 dot per second
..... // print 1 dot per second
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // for printf(), putchar(), NULL
#include <stdlib.h> // for getenv()
extern char **environ; // the environment
int main ()
{
printf ("USER=%s\n", getenv("USER"));
printf ("HOME=%s\n", getenv("HOME"));
printf ("PATH=%s\n", getenv("PATH"));
printf ("DISPLAY=%s\n", getenv("DISPLAY"));
putchar('\n');
char **var;
for (var = environ; *var != NULL; var++)
{printf ("%s\n", *var);}
return 0;
}
/*
gcc printenv.c -o printenv
./printenv
USER=user
HOME=/home/user
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:.
DISPLAY=:0
SHELL=/bin/bash
...
PWD=/home/user/.../printenv
...
LANG=en_US.UTF-8
...
BROWSER=firefox
...
_=./printenv
echo $SHELL
/bin/bash
echo $BROWSER
firefox
echo $_
firefox
cd ..
echo $_
..
echo $1
echo $_
echo
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // for printf()
#include <stdlib.h> // for getenv()
int main ()
{
char *server_name = getenv ("SERVER_NAME");
if (server_name == NULL)
{ // SERVER_NAME environment variable not set, use
server_name = "server.my-company.com"; // the default
}
printf ("Accessing server \"%s\"\n", server_name);
/* Access the server here... */
return 0;
}
/*
gcc client.c -o client
./client
Accessing server "server.my-company.com"
export SERVER_NAME=backup-server.elsewhere.net
/client
Accessing server "backup-server.elsewhere.net"
*/
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
*********************************************************************************
#include <stdio.h> // for printf(), fprintf(), stderr, NULL, FILE,
// fread(), fwrite(), SEEK_SET, fseek(), fclose(), tmpfile(), size_t
/*
stdio.h includes stddef.h, which defines size_t:
/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h:
#define __SIZE_TYPE__ long unsigned int
typedef __SIZE_TYPE__ size_t
typedef long ssize_t
*/
// stdlib.h, string.h, and unistd.h also include stddef.h
#include <stdlib.h> // for malloc(), free(), mkstemp(), exit()
#include <string.h> // for strlen()
#include <unistd.h> // for read(), write(), lseek(), close(), unlink()
#define MAXWORD 100 // max word length
// high level operations
FILE * fwrite_tempfile (char *buffer, size_t length);
char * fread_tempfile (FILE *fp, size_t *length);
// low level operations
int write_tempfile (char *buffer, size_t length);
char * read_tempfile (int fd, size_t *length);
int main()
{
char word[MAXWORD];
size_t len; // word length
printf("Type a word: ");
scanf("%s", word);
len = strlen(word);
FILE *fp;
char *buf; // buffer
size_t length; // returned length
fp = fwrite_tempfile(word, len+1); // +1 for ending '\0'
buf = fread_tempfile(fp, &length);
printf("You typed: \"%s\", length: %lu\n", buf, length-1);
int fd; // file descriptor for temporary file
fd = write_tempfile(word, len+1); // +1 for ending '\0'
buf = read_tempfile(fd, &length);
printf("You typed: \"%s\", length: %lu\n", buf, length-1);
free(buf);
return 0;
}
/* Writes `length' bytes from `buffer' into a temporary file.
The temporary file will be deleted automatically at the end
of the program. Returns a handle (FILE *) to the temporary file. */
FILE * fwrite_tempfile (char* buffer, size_t length)
{
FILE *fp = tmpfile();
/* Write the number of bytes to the file first: */
fwrite (&length, sizeof(length), 1, fp); // sizeof(byte) == 1 byte
/* Now write the data itself: */
fwrite (buffer, length, sizeof(char), fp);
/* Use the file pointer as the handle for the temporary file: */
return fp;
}
/* Reads the contents of a temporary file with file pointer `fp'
created with write_tempfile(). The return value is a newly allocated
buffer of those contents, which the caller must deallocate with free.
*length is set to the size of the contents, in bytes.
The temporary file is removed at the end. */
char * fread_tempfile (FILE *fp, size_t *length)
{ // should check if fp != NULL
char *buffer;
/* Rewind to the beginning of the file: */
fseek (fp, 0, SEEK_SET);
/* Read the size of the data from the temporary file: */
fread (length, sizeof(*length), 1, fp); // sizeof(byte) == 1 byte
/* Allocate a buffer and read the data. */
buffer = (char*) malloc (*length);
if (buffer == NULL)
{
fprintf(stderr, "fread_tempfile: could not allocate buffer\n");
exit(1); // end program, signalling error
}
// else
fread (buffer, *length, sizeof(char), fp);
/* Close the file, which will cause the temporary file to go away: */
fclose(fp); // temporary file will be deleted automatically
// at the end of the program
return buffer;
}
/* Writes `length' bytes from `buffer' into a temporary file.
The temporary file is immediately unlinked.
Returns a handle (file descriptor) to the temporary file. */
int write_tempfile (char *buffer, size_t length)
{
/* Create the filename and file. The XXXXXX will be replaced with
characters that make the filename unique. */
char temp_filename[] = "/tmp/temp_file.XXXXXX";
int fd = mkstemp(temp_filename);
/* Unlink the file immediately, so that it will be removed when the
file descriptor is closed: */
unlink (temp_filename);
/* Write the number of bytes to the file first: */
write (fd, &length, sizeof(length));
/* Now write the data itself: */
write (fd, buffer, length);
/* Use the file descriptor as the handle for the temporary file: */
return fd;
}
/* Reads the contents of a temporary file with file descriptor `fd'
created with write_tempfile(). The return value is a newly allocated
buffer of those contents, which the caller must deallocate with free().
*length is set to the size of the contents, in bytes.
The temporary file is removed at the end. */
char * read_tempfile (int fd, size_t *length)
{ // should check if fd >= 0
char* buffer;
lseek (fd, 0, SEEK_SET); // Rewind to the beginning of the file
/* Read the size (length) of the data from the temporary file: */
read (fd, length, sizeof(*length));
/* Allocate a buffer and read the data: */
buffer = (char*) malloc(*length);
if (buffer == NULL)
{
fprintf(stderr, "read_tempfile: could not allocate buffer\n");
exit(1); // end program, signalling error
}
// else
read(fd, buffer, *length);
close(fd); // close file descriptor, removing temporary file
return buffer;
}
/*
gcc tempfile.c -o tempfile
./tempfile
Type a word: Hello!
You typed: "Hello!", length: 6
You typed: "Hello!", length: 6
*/