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 ; }