man ascii
ASCII and ctype
int isxdigit(int c){return isdigit(c) || ((unsigned)c|32)-'a' < 6;}

|32保证了可以检测到A等大写字母,因为ASCII码为65,aASCII码为97,如果或上32,就相当于补上了他们的差值32。
strcpy and strncpy
char *strcpy(char *dst, const char *src){char *result = dst;while ((*dst++ = *src++)) ;return result;}// taken from the strncpy man pagechar *strncpy(char *dest, const char *src, size_t n){size_t i;for (i = 0; i < n && src[i] != '\0'; i++)dest[i] = src[i];for ( ; i < n; i++)dest[i] = '\0';return dest;}
Aside: In the days of yore, pointer arithmetic had a performance advantage over array indexing, but smart modern compilers make this largely moot. A lot of old code and old programmers haven’t yet gotten that memo. Pointer arithmetic is especially rife in code that wrangles C-strings where it is perhaps tolerable, but for arrays of type other than char, array indexing is almost always going to be more readable.
gdb x command
(gdb) x/8bc buf
buf是main中的一个变量。
Using Valgrind
myprintenv
echo $USER $HOST $HOME $SHELL
printenv, 打印环境变量。env,修改环境变量
c编程获取并打印环境变量
/** File: myprintenv.c* ------------------* Read lab2 writeup for more information.*/#include <stdio.h>#include <string.h>const char *get_env_value(const char *envp[], const char *varname){for (int i = 0; envp[i] != NULL; i++){//printf("%s\n", envp[i]);char *result = strstr(envp[i], varname);if (result == envp[i]){//if result is null, don't do anything//envp[i] can be null but will be blocked by forresult += strlen(varname);if (*result == '=')return ++result;}}return NULL; // TODO}/* Function: main* --------------* Ordinarily main() has just two arguments (argc/argv); this alternate* prototype includes an optional third argument which is an array of* environment variables (like argc/argv, the values passed to this third* arg are set automatically by the operating system when the program is* launched). Programs can use either form for main. The 2-argument* version is more common, but this program will use the main with* 3rd argument to get access to the environment variables.* (In fact, many programmers don't even know about this optional 3rd* argument, so now you're already elite! :-) )** Each array entry in this third argument is a string (pointer char*),* where the string pointed to is of the form "NAME=value", for different* environment variable NAMEs and configuration values. The array's last* entry is a NULL pointer, which acts as a sentinel to identify the* end of the array (which is why we can get away with not including an* accompanying array size argument, as we would normally do when passing* arrays in C).*/int main(int argc, char *argv[], const char *envp[]){if (argc == 1) {for (int i = 0; envp[i] != NULL; i++)printf("%s\n", envp[i]);} else {for (int i = 1; i < argc; i++) {const char *value = get_env_value(envp, argv[i]);if (value != NULL) // if not found, don't print anythingprintf("%s\n", value);}}return 0;}
代码逻辑非常棒。


