📄 18.txt
字号:
CS 1355
Introduction to Programming in C
Thursday 2006.11.16 (Week 10)
Lecture notes (at http://r638-2.cs.nthu.edu.tw/C/notes/18.txt)
Chapter 8: C Characters and Strings
- Character classes
- Strings
- string comparison
- I/O
Before we begin: the conditional operator
syntax:
condition ? A : B
What it means:
if condition is true, then the whole expression has value of A
if condition is false, then the whole expression has value of B
This is a "ternary" operator (3 subexpressions)
Character classes:
- control characters vs. printable characters
control: for moving the cursor
printable: has a shape
- printable
- digit: 0-9
- alpha: A-Z, a-z
- upper: A-Z
- lower: a-z
- alnum: 0-9, A-Z, a-z
- xdigit: (hexadecimal digit, 16?蹭?) A-F, a-f, 0-9
- space: space, newline \n, formfeed \f, return \r,
horizontal tab \t, vertical tab \v
- punctuation
- graphical characters
Library functions for character-class query
- int isdigit(int c); << return value is boolean,
parameter c is character
- int isalpha(int c);
- int isalnum(int c);
- int isxdigit(int c);
- int islower(int c);
- int isupper(int c);
- int isspace(int c);
- int iscntrl(int c);
- int ispunct(int c);
- int isprint(int c);
- int isgraph(int c);
Library functions for character conversion
- int tolower(int c); << converts 'A' to 'a'
- int toupper(int c); << converts 'a' to 'A'
Library function for string conversion
- double atof(const char *n); /* "ascii to float" */
- int atoi(const char *n); /* "ascii to int */
- long atol(const char *n); /* "ascii to long */
- double strtod(const char *n, char **endPtr); /* string to double */
- long strtol(const char *nptr, char **endPtr, int base);
/* string to long */
- unsigned long strtoul(const char *n, char **endtr, int base);
meaning of "base"
- can be different from base 10.
- 0 is the default
Standard I/O library functions
- int getchar(void); /* get next char, or EOF */
=> this is like
char temp;
return scanf("%c", &temp) == EOF? EOF : temp;
- char *gets(char buf[]); /* read up to end of line. dangerous!! */
/* return value is the same as buf[].
does not include \n, but inserts \0 */
=> Better to use fgets() instead of gets()!
fgets() takes 3 arguments, including length
- int putchar(int c); /* write c to output */
=> this is like printf("%c", c);
- int puts(const char buf[]); /* write string, plus \n */
=> this is like printf("%s\n", buf);
stdio.h string utility function
- int sprintf(char buf[ ], const char *format, ...);
- int sscanf(char buf[ ], const char *format, ...);
=> sprintf is like printf, except it "prints to the memory buffer",
=> sscanf is like scanf, except it "scans from the memory buffer"
problem: sscanf() does not keep track of the state of scanning!!
One common use
- use fgets() to read a whole line
- use various "scanning" (scanf, strtoi, ...) to extract strings
and their values
String copying and concentation
- char *strcpy(char *s1, const char *s2); /* "string copy" */
=> think s1 = s2; like an assignment statement
return value is s1!
- char *strncpy(char *s1, const char *s2, size_t n);
- char *strcat(char *s1, const char *s2); /* string concaentate */
=> string concatenation (join). but it actually is more like "append"
(add to the tail)
=> copies s2 to the end of s1's buffer!
- char *strncat(char *s1, const char *s2, size_t);
/* string-N-concatenation */
=> copies up to n character of s2 to the end of s1. return s1 */
String comparison functions
- size_t strlen(char *s); /* string length */
/* size_t is an integer type */
- int strcmp(char *x, char *y); /* compare string */
- int strncmp(char *x, char *y, int len); /* compare up to length len */
- in "lexicographical" order (dictionary order)
"a" < "aa" < "aaa" < "aaaaaa" < "ab" < "aba" <"abb" < "ac" < "ad" < ...
< "b" < "ba" < "baa" < "bab" < ...
C language itself does not support string comparison,
use library function instead!
i.e., cannot say
if ("abc" < "gaugadi") { ... }
must say
if (strcmp("abc", "gaugadi" < 0)) { ... }
- strcmp() means
- compare characters x[i] and y[i]
- if different, then return
greater (> 0) or smaller (< 0)
- if same,
- both null => return same (0)
- (both not null) => compare x[i+1] and y[i+1]
We can write it recursively
int strcmp(char *x, char *y) {
int diff = *x - *y;
if (diff || !*x || !*y) return diff; /* > 0 or < 0, or == 0 */
return strcmp(x+1, y+1);
}
Book says 0, 1, -1, but in practice, it doesn't have to be 1, -1
just has to be value > 0 or < 0
String "Search" functions
- char *strchr(const char *s, int c);
/* find position if first c in string s
if not found, return NULL pointer */
- size_t strcspn(const char *s1, const char *s2);
/* length of string from beginning of s1 up to first char in s2 */
/* treating s2 as a set of char */
example:
strcspn("The value is 3.14159", "1234567890");
=> return value is 13,
because "The value is " does not contain any of 1234567890.
General memory functions (rather than string)
void *memcpy(void *s1, void *s2, size_t n);
/* copies s2[0..n-1] to s1[0..n-1] */
int memcmp(const void* s1, const void *s2, size_t n);
/* compare exactly n */
void *memchr(const void *s, int c, size_t n);
/* find first position of c in s[0..n-1] */
What's the difference?
- string is null terminated
- mem is n-terminated (exact size)
Why use these library functions?
- because they have been "optimized", run very efficiently
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -