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 *CourseNane3 = "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 courseA[2][29] = {
"ECE209",
"Computer Systems Programming"
} ;
char *courseP[2] = {
"ECE209",
"Computer Systems Programming"
} ;
According to my C compiler (32-bit Intel), sizeof courseA is
58 and sizeof courseB is 8.
However, courseB 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 courseB.
scanf |
Read 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. |
fgets |
Read file input up to next newline. Do not discard newline character. Avoids buffer overflow by limiting number of read characters. |
scanf |
Read 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. |
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.
|
atof |
Converts a string into an int.
Fails pretty 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 sprintf 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 used the non-void
prototype.
int main(int argc, char **argv) ;
argc is the number of command line arguments and
argv[i] is the i'th
command line arguments. The name of the program will be
argv[0].
Try writing some of the following tasks.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[]) {
int i, j ;
for (i=0; i<argc-1; ++i) {
char *t ;
int minPos = i ;
for(j=i+1; j<argc; ++j)
if (strcmp(argv[j], argv[minPos]) < 0)
minPos = j ;
t = argv[i] ;
argv[i] = argv[minPos] ;
argv[minPos] = t ;
}
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>
int main(int argc, char* argv[]) {
int i, j, n ;
n = 0 ;
for (i=0; i<argc; ++i) {
char *endNumber ;
strtod(argv[i], &endNumber) ;
if (endNumber != argv[i] && *endNumber == '\0') {
argv[n] = argv[i] ;
++n ;
}
}
for (i=0; i<n-1; ++i) {
char *t ;
int minPos = i ;
double minNum = strtod(argv[minPos], (char **)NULL) ;
for(j=i+1; j<n; ++j) {
double jNum = strtod(argv[j], (char **)NULL) ;
if (jNum < minNum) {
minPos = j ;
minNum = jNum ;
}
}
t = argv[i] ;
argv[i] = argv[minPos] ;
argv[minPos] = t ;
}
for (i=0; i<n; ++i)
printf(" %2d: %s\n", i, argv[i]) ;
return (EXIT_SUCCESS);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BSIZE 100
int Transform(const char *, char *) ;
int main(int argc, char* argv[]) {
char outString[2*BSIZE] ;
if (argc < 1)
return EXIT_FAILURE ;
if (strlen(argv[1]) > BSIZE)
return EXIT_FAILURE ;
if (!Transform(argv[1], outString)) {
printf("\"%s\" ==> \"%s\"\n", argv[1], outString) ;
return EXIT_SUCCESS;
} else
return EXIT_FAILURE ;
}
#include <string.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>
int Transform(const char *inString, char *outString) {
char *lastNameP ;
if ((lastNameP = strrchr(inString, ' ')) == NULL)
return 1 ;
sprintf(outString, "%s, %.*s", lastNameP+1, 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, "2009", 4) ;
outString += 4 ;
}
return 0 ;
}