krx50500.c
来自「answer of the c programming language sec」· C语言 代码 · 共 155 行
C
155 行
/* * Solution to exercise 5-5 in K&R2, page 107: * * Write versions of the library functions strncpy, strncat, * and strncmp, which operate on at most the first n characters * of their argument strings. For example, strncpy(s,t,n) copies * at most n characters of t to s. Full descriptions are in * Appendix B. * * Note that the description in the exercise is not precise. Here are * descriptions from Appendix B (though one should really follow the * descriptions in the standard): * * char *strncpy(s,ct,n) copy at most n characters of string ct * to s, return s. Pad with '\0's is ct * has fewer than n characters. * char *strncat(s,ct,n) concatenate at most n characters of * string ct to string s, terminate s with * '\0'; return s. * int strncmp(cs,ct,n) compare at most n characters of string * cs to string ct; return <0 if cs<ct, * 0 if cs==ct, or >0 if cs>ct. * * Further note that the standard requires strncmp to compare the * characters using unsigned char internally. * * Implementation note: since the function names are reserved by the * standard, I've used the prefix `liw_'. This also allows me to check * the functions against the standard library versions. For each library * function, I've written a test function that tests a particular test * case. Where appropriate, the test functions use internal buffers that * are of size MAX_BUF; at least some of the test cases should be longer * to test all boundary conditions. * * Feel free to modify, copy, and use as you wish. * * Lars Wirzenius <liw@iki.fi> */#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAX_BUF 16char *liw_strncpy(char *s, const char *ct, size_t n) { char *p; p = s; for (; n > 0 && *ct != '\0'; --n) *p++ = *ct++; for (; n > 0; --n) *p++ = '\0'; return s;}char *liw_strncat(char *s, const char *ct, size_t n) { char *p; p = s; while (*p != '\0') ++p; for (; n > 0 && *ct != '\0'; --n) *p++ = *ct++; *p = '\0'; return s;}int liw_strncmp(const char *cs, const char *ct, size_t n) { while (n > 0 && *cs == *ct && *cs != '\0') { ++cs; ++ct; --n; } if (n == 0 || *cs == *ct) return 0; if (*(unsigned char *) cs < *(unsigned char *) ct) return -1; return 1;}void test_ncpy(const char *str) { char std_buf[MAX_BUF]; char liw_buf[MAX_BUF]; memset(std_buf, 0x42, sizeof(std_buf)); strncpy(std_buf, str, sizeof(std_buf)); memset(liw_buf, 0x42, sizeof(liw_buf)); liw_strncpy(liw_buf, str, sizeof(liw_buf)); if (memcmp(std_buf, liw_buf, sizeof(std_buf)) != 0) { fprintf(stderr, "liw_strncpy failed for <%s>\n", str); exit(EXIT_FAILURE); }}void test_ncat(const char *first, const char *second) { char std_buf[MAX_BUF]; char liw_buf[MAX_BUF]; memset(std_buf, 0x69, sizeof(std_buf)); strcpy(std_buf, first); strncat(std_buf, second, sizeof(std_buf) - strlen(std_buf) - 1); memset(liw_buf, 0x69, sizeof(liw_buf)); strcpy(liw_buf, first); liw_strncat(liw_buf, second, sizeof(liw_buf) - strlen(liw_buf) - 1); if (memcmp(std_buf, liw_buf, sizeof(std_buf)) != 0) { fprintf(stderr, "liw_strncat failed, <%s> and <%s>\n", first, second); exit(EXIT_FAILURE); }}void test_ncmp(const char *first, const char *second) { size_t len; int std_ret, liw_ret; if (strlen(first) < strlen(second)) len = strlen(second); else len = strlen(first); std_ret = strncmp(first, second, len); liw_ret = liw_strncmp(first, second, len); if ((std_ret < 0 && liw_ret >= 0) || (std_ret > 0 && liw_ret <= 0) || (std_ret == 0 && liw_ret != 0)) { fprintf(stderr, "liw_strncmp failed, <%s> and <%s>\n", first, second); exit(EXIT_FAILURE); }}int main(void) { test_ncpy(""); test_ncpy("a"); test_ncpy("ab"); test_ncpy("abcdefghijklmnopqrstuvwxyz"); /* longer than MAX_BUF */ test_ncat("", "a"); test_ncat("a", "bc"); test_ncat("ab", "cde"); test_ncat("ab", "cdefghijklmnopqrstuvwxyz"); /* longer than MAX_BUF */ test_ncmp("", ""); test_ncmp("", "a"); test_ncmp("a", "a"); test_ncmp("a", "ab"); test_ncmp("abc", "ab"); printf("All tests pass.\n"); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?