char CourseName1[] = "Computer Systems Programming" ;
char CourseName2[] = {
'C', 'o', 'm', 'p', 'u', 't', 'e', 'r', ' ',
'S', 'y', 's', 't', 'e', 'm', 's', ' ',
'P', 'r', 'o', 'g', 'r', 'a', 'm', 'm', 'i', 'n', 'g', '\0'
} ;
char CourseName3[40] = "Computer Systems Programming" ;
char *CourseName4 = "Computer Systems Programming" ;
CourseName1 and CourseName2 are identical.
29 characters are allocated for each.
CourseName3 has an extra unused 11 characters at the end.
CourseName1, CourseName2,
and CourseName3 before each use and can be
safely overwritten.
CourseName4 points to a
string stored in read-only memory.
char courseD[2][29] = {
"ECE209",
"Computer Systems Programming"
} ;
char *courseP[2] = {
"ECE209",
"Computer Systems Programming"
} ;
According to my C compiler (32-bit Intel), sizeof courseD is
58 and sizeof courseP is 8.
However, courseP really requires another 36 (7+29) bytes of
memory where the actual strings are stored.
There probably is another 58 bytes of storage set aside for the
"original" copy of courseD.
scanf |
Reads strings with %s.
Skips beginning whitespace and stops at whitespace.
Can avoid buffer overflow with width specifier, e.g., %10s.
|
gets |
Reads standard input up to next newline. Discards newline character. Does not provide a way to avoid buffer overflow. Should not be used. |
fgets |
Reads file input up to next newline. Does not discard newline character. Avoids buffer overflow by limiting number of read characters. |
scanf |
Reads strings with %s.
Skips beginning whitespace and stops at whitespace.
Can avoid buffer overflow with width specifier, e.g., %10s.
|
gets |
Reads standard input up to next newline. Discards newline character. Does not provide a way to avoid buffer overflow. Should not be used. |
fgets |
Read file input up to next newline. Do not discard newline character. Avoids buffer overflow by limiting number of read characters. |
printf |
Writes strings with %s.
Outputs size can be limited with width specifier, e.g., %10s.
|
puts |
Writes string to standard output. Appends newline at end of string. Does not provide a way to limit output size. |
fputs |
Writes string to file output. Do not append a newline character. Does not provide a way to limit output size. |
atof |
Converts a string into a double.
Fails gracelessly.
|
atoi |
Converts a string into an int.
Fails gracelessly.
|
strtol |
Converts a string into a long int.
Harder to use than atol, but much safer.
Allows the use of bases other than 10.
|
strtod |
Converts a string into a double.
Harder to use than atof, but much safer.
|
sscanf |
A scanf from a string, not a file.
|
sprintf |
A printf to a string, not a file.
|
There are lots of functions in this library.
Many of these come in strn... variants which
limit the number of characters copied or checked.
strlen |
Counts the number of characters in a string. |
strcpy |
Copies a string. |
strcat |
Concatenates one strings onto the end of another. |
strcmp |
Compares two strings. Returns a negative number, if the first is less than the second; a positive number, if the first is greater than the second; and zero, if the two are equal. |
strchr |
Finds the first occurrence of a character within a string. |
strrchr |
Finds the last (rightmost) occurrence of a character within a string. |
strstr |
Finds the first occurrence of one string within another. |
To read command-line arguments use the
prototype without the void arguments.
int main(int argc, char *argv[]) ;
argc is the number of command line arguments and
argv[i] is the i'th
command line argument.
argv[0] contains the name of the program.
Try writing some of the following tasks.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
int i ;
for (i=0; i<argc; ++i) {
printf(" %2d: %s\n", i, argv[i]) ;
}
return (EXIT_SUCCESS);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXINSIZE 100
#define MAXOUTSIZE 1000
#include "transform.h"
int main(int argc, char* argv[]) {
char outString[MAXOUTSIZE] ;
if (argc < 2) {
fputs("Needs an argument\n", stderr) ;
return EXIT_FAILURE ;
}
if (strlen(argv[1]) > BSIZE) {
fputs("Needs a smaller argument\n", stderr) ;
return EXIT_FAILURE ;
}
if (!Transform(argv[1], outString)) {
printf("\"%s\" ==> \"%s\"\n", argv[1], outString) ;
return EXIT_SUCCESS;
} else
fputs("Transform failed\n", stderr) ;
return EXIT_FAILURE ;
}
#include <string.h>
#include "transform.h"
int Transform(const char *inString, char *outString) {
char *lastNameP ;
int firstPartSize, nameSize ;
if ((lastNameP = strrchr(inString, ' ')) == NULL) {
return 1 ;
}
nameSize = strlen(inString) ;
firstPartSize = lastNameP - inString ;
strcpy(outString, lastNameP+1) ;
strcat(outString, ", ") ;
strncat(outString, inString, firstPartSize) ;
outString[nameSize+1] = '\0' ;
return 0 ;
}
#include <string.h>
#include <stdio.h>
#include "transform.h"
int Transform(const char *inString, char *outString) {
char *lastNameP ;
if ((lastNameP = strrchr(inString, ' ')) == NULL) {
return 1 ;
}
sprintf(outString, "%s, %.*s", lastNameP+1, (int)(lastNameP-inString), inString) ;
return 0 ;
}
#include <string.h>
#include <ctype.h>
int Transform(const char *inString, char *outString) {
char *lastNameP, *middleNameP, *lastOfOutput ;
if ((lastNameP = strrchr(inString, ' ')) == NULL) {
return 1 ;
}
strncpy(outString, lastNameP+1, 6) ;
outString[0] = tolower(outString[0]) ;
outString[6] = '\0' ;
lastOfOutput = outString + strlen(outString) ;
*lastOfOutput++ = tolower(inString[0]) ;
middleNameP = strchr(inString, ' ') ;
if (middleNameP != lastNameP) {
*lastOfOutput++ = tolower(middleNameP[1]) ;
}
*lastOfOutput = '\0' ;
return 0 ;
}
#include <string.h>
int Transform(const char *inString, char *outString) {
char *outP, *matchP ;
strcpy(outString, inString) ;
outP = outString ;
while ((matchP = strstr(outString, "2008")) != NULL) {
strncpy(matchP, "2011", 4) ;
outString += 4 ;
}
return 0 ;
}