📄 string.c
字号:
check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */ check(memcmp("abce", "abcd", 4) > 0, 4); check(memcmp("alph", "beta", 4) < 0, 5); check(memcmp("a\203", "a\003", 2) > 0, 6); check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */ check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */}static voidtest_memchr (void){ it = "memchr"; check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */ (void) strcpy(one, "abcd"); check(memchr(one, 'c', 4) == one+2, 2); /* Basic test. */ check(memchr(one, ~0xff|'c', 4) == one+2, 2); /* ignore highorder bits. */ check(memchr(one, 'd', 4) == one+3, 3); /* End of string. */ check(memchr(one, 'a', 4) == one, 4); /* Beginning. */ check(memchr(one, '\0', 5) == one+4, 5); /* Finding NUL. */ (void) strcpy(one, "ababa"); check(memchr(one, 'b', 5) == one+1, 6); /* Finding first. */ check(memchr(one, 'b', 0) == NULL, 7); /* Zero count. */ check(memchr(one, 'a', 1) == one, 8); /* Singleton case. */ (void) strcpy(one, "a\203b"); check(memchr(one, 0203, 3) == one+1, 9); /* Unsignedness. */ /* now test all possible alignment and length combinations to catch bugs due to unrolled loops (assuming unrolling is limited to no more than 128 byte chunks: */ { char buf[128 + sizeof(long)]; long align, len, i, pos; for (align = 0; align < (long) sizeof(long); ++align) { for (len = 0; len < (long) (sizeof(buf) - align); ++len) { for (i = 0; i < len; ++i) { buf[align + i] = 'x'; /* don't depend on memset... */ } for (pos = 0; pos < len; ++pos) {#if 0 printf("align %d, len %d, pos %d\n", align, len, pos);#endif check(memchr(buf + align, 'x', len) == buf + align + pos, 10); check(memchr(buf + align, 'x', pos) == NULL, 11); buf[align + pos] = '-'; } } } }}static voidtest_memcpy (void){ int i; it = "memcpy"; check(memcpy(one, "abc", 4) == one, 1); /* Returned value. */ equal(one, "abc", 2); /* Did the copy go right? */ (void) strcpy(one, "abcdefgh"); (void) memcpy(one+1, "xyz", 2); equal(one, "axydefgh", 3); /* Basic test. */ (void) strcpy(one, "abc"); (void) memcpy(one, "xyz", 0); equal(one, "abc", 4); /* Zero-length copy. */ (void) strcpy(one, "hi there"); (void) strcpy(two, "foo"); (void) memcpy(two, one, 9); equal(two, "hi there", 5); /* Just paranoia. */ equal(one, "hi there", 6); /* Stomped on source? */ for (i = 0; i < 16; i++) { const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; strcpy (one, x); check (memcpy (one + i, "hi there", 9) == one + i, 7 + (i * 6)); /* Unaligned destination. */ check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */ equal (one + i, "hi there", 9 + (i * 6)); check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */ check (memcpy (two, one + i, 9) == two, 11 + (i * 6)); /* Unaligned source. */ equal (two, "hi there", 12 + (i * 6)); }}static voidtest_mempcpy (void){ int i; it = "mempcpy"; check(mempcpy(one, "abc", 4) == one + 4, 1); /* Returned value. */ equal(one, "abc", 2); /* Did the copy go right? */ (void) strcpy(one, "abcdefgh"); (void) mempcpy(one+1, "xyz", 2); equal(one, "axydefgh", 3); /* Basic test. */ (void) strcpy(one, "abc"); (void) mempcpy(one, "xyz", 0); equal(one, "abc", 4); /* Zero-length copy. */ (void) strcpy(one, "hi there"); (void) strcpy(two, "foo"); (void) mempcpy(two, one, 9); equal(two, "hi there", 5); /* Just paranoia. */ equal(one, "hi there", 6); /* Stomped on source? */ for (i = 0; i < 16; i++) { const char *x = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; strcpy (one, x); check (mempcpy (one + i, "hi there", 9) == one + i + 9, 7 + (i * 6)); /* Unaligned destination. */ check (memcmp (one, x, i) == 0, 8 + (i * 6)); /* Wrote under? */ equal (one + i, "hi there", 9 + (i * 6)); check (one[i + 9] == 'x', 10 + (i * 6)); /* Wrote over? */ check (mempcpy (two, one + i, 9) == two + 9, 11 + (i * 6)); /* Unaligned source. */ equal (two, "hi there", 12 + (i * 6)); }}static voidtest_memmove (void){ it = "memmove"; check(memmove(one, "abc", 4) == one, 1); /* Returned value. */ equal(one, "abc", 2); /* Did the copy go right? */ (void) strcpy(one, "abcdefgh"); (void) memmove(one+1, "xyz", 2); equal(one, "axydefgh", 3); /* Basic test. */ (void) strcpy(one, "abc"); (void) memmove(one, "xyz", 0); equal(one, "abc", 4); /* Zero-length copy. */ (void) strcpy(one, "hi there"); (void) strcpy(two, "foo"); (void) memmove(two, one, 9); equal(two, "hi there", 5); /* Just paranoia. */ equal(one, "hi there", 6); /* Stomped on source? */ (void) strcpy(one, "abcdefgh"); (void) memmove(one+1, one, 9); equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */ (void) strcpy(one, "abcdefgh"); (void) memmove(one+1, one+2, 7); equal(one, "acdefgh", 8); /* Overlap, left-to-right. */ (void) strcpy(one, "abcdefgh"); (void) memmove(one, one, 9); equal(one, "abcdefgh", 9); /* 100% overlap. */}static voidtest_memccpy (void){ /* First test like memcpy, then the search part The SVID, the only place where memccpy is mentioned, says overlap might fail, so we don't try it. Besides, it's hard to see the rationale for a non-left-to-right memccpy. */ it = "memccpy"; check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */ equal(one, "abc", 2); /* Did the copy go right? */ (void) strcpy(one, "abcdefgh"); (void) memccpy(one+1, "xyz", 'q', 2); equal(one, "axydefgh", 3); /* Basic test. */ (void) strcpy(one, "abc"); (void) memccpy(one, "xyz", 'q', 0); equal(one, "abc", 4); /* Zero-length copy. */ (void) strcpy(one, "hi there"); (void) strcpy(two, "foo"); (void) memccpy(two, one, 'q', 9); equal(two, "hi there", 5); /* Just paranoia. */ equal(one, "hi there", 6); /* Stomped on source? */ (void) strcpy(one, "abcdefgh"); (void) strcpy(two, "horsefeathers"); check(memccpy(two, one, 'f', 9) == two+6, 7); /* Returned value. */ equal(one, "abcdefgh", 8); /* Source intact? */ equal(two, "abcdefeathers", 9); /* Copy correct? */ (void) strcpy(one, "abcd"); (void) strcpy(two, "bumblebee"); check(memccpy(two, one, 'a', 4) == two+1, 10); /* First char. */ equal(two, "aumblebee", 11); check(memccpy(two, one, 'd', 4) == two+4, 12); /* Last char. */ equal(two, "abcdlebee", 13); (void) strcpy(one, "xyz"); check(memccpy(two, one, 'x', 1) == two+1, 14); /* Singleton. */ equal(two, "xbcdlebee", 15);}static voidtest_memset (void){ int i; it = "memset"; (void) strcpy(one, "abcdefgh"); check(memset(one+1, 'x', 3) == one+1, 1); /* Return value. */ equal(one, "axxxefgh", 2); /* Basic test. */ (void) memset(one+2, 'y', 0); equal(one, "axxxefgh", 3); /* Zero-length set. */ (void) memset(one+5, 0, 1); equal(one, "axxxe", 4); /* Zero fill. */ equal(one+6, "gh", 5); /* And the leftover. */ (void) memset(one+2, 010045, 1); equal(one, "ax\045xe", 6); /* Unsigned char convert. */ /* Non-8bit fill character. */ memset (one, 0x101, sizeof (one)); for (i = 0; i < (int) sizeof (one); ++i) check (one[i] == '\01', 7); /* Test for more complex versions of memset, for all alignments and lengths up to 256. This test takes a little while, perhaps it should be made weaker? */ { char data[512]; int j; int k; int c; for (i = 0; i < 512; i++) data[i] = 'x'; for (c = 0; c <= 'y'; c += 'y') /* check for memset(,0,) and memset(,'y',) */ for (j = 0; j < 256; j++) for (i = 0; i < 256; i++) { memset (data + i, c, j); for (k = 0; k < i; k++) if (data[k] != 'x') goto fail; for (k = i; k < i+j; k++) { if (data[k] != c) goto fail; data[k] = 'x'; } for (k = i+j; k < 512; k++) if (data[k] != 'x') goto fail; continue; fail: check (0, 8 + i + j * 256 + (c != 0) * 256 * 256); } }}static voidtest_bcopy (void){ /* Much like memcpy. Berklix manual is silent about overlap, so don't test it. */ it = "bcopy"; (void) bcopy("abc", one, 4); equal(one, "abc", 1); /* Simple copy. */ (void) strcpy(one, "abcdefgh"); (void) bcopy("xyz", one+1, 2); equal(one, "axydefgh", 2); /* Basic test. */ (void) strcpy(one, "abc"); (void) bcopy("xyz", one, 0); equal(one, "abc", 3); /* Zero-length copy. */ (void) strcpy(one, "hi there"); (void) strcpy(two, "foo"); (void) bcopy(one, two, 9); equal(two, "hi there", 4); /* Just paranoia. */ equal(one, "hi there", 5); /* Stomped on source? */}static voidtest_bzero (void){ it = "bzero"; (void) strcpy(one, "abcdef"); bzero(one+2, 2); equal(one, "ab", 1); /* Basic test. */ equal(one+3, "", 2); equal(one+4, "ef", 3); (void) strcpy(one, "abcdef"); bzero(one+2, 0); equal(one, "abcdef", 4); /* Zero-length copy. */}static voidtest_strndup (void){ char *p, *q; it = "strndup"; p = strndup("abcdef", 12); check(p != NULL, 1); if (p != NULL) { equal(p, "abcdef", 2); q = strndup(p + 1, 2); check(q != NULL, 3); if (q != NULL) equal(q, "bc", 4); free (q); } free (p); p = strndup("abc def", 3); check(p != NULL, 5); if (p != NULL) equal(p, "abc", 6); free (p);}static voidtest_bcmp (void){ it = "bcmp"; check(bcmp("a", "a", 1) == 0, 1); /* Identity. */ check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */ check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */ check(bcmp("abce", "abcd", 4) != 0, 4); check(bcmp("alph", "beta", 4) != 0, 5); check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */ check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */}static voidtest_strerror (void){ it = "strerror"; check(strerror(EDOM) != 0, 1); check(strerror(ERANGE) != 0, 2); check(strerror(ENOENT) != 0, 3);}intmain (void){ int status; /* Test strcmp first because we use it to test other things. */ test_strcmp (); /* Test strcpy next because we need it to set up other tests. */ test_strcpy (); /* A closely related function is stpcpy. */ test_stpcpy (); /* stpncpy. */ test_stpncpy (); /* strcat. */ test_strcat (); /* strncat. */ test_strncat (); /* strncmp. */ test_strncmp (); /* strncpy. */ test_strncpy (); /* strlen. */ test_strlen (); /* strchr. */ test_strchr (); /* strchrnul. */ test_strchrnul (); /* rawmemchr. */ test_rawmemchr (); /* index - just like strchr. */ test_index (); /* strrchr. */ test_strrchr (); /* memrchr. */ test_memrchr (); /* rindex - just like strrchr. */ test_rindex (); /* strpbrk - somewhat like strchr. */ test_strpbrk (); /* strstr - somewhat like strchr. */ test_strstr (); /* strspn. */ test_strspn (); /* strcspn. */ test_strcspn (); /* strtok - the hard one. */ test_strtok (); /* strtok_r. */ test_strtok_r (); /* strsep. */ test_strsep (); /* memcmp. */ test_memcmp (); /* memchr. */ test_memchr (); /* memcpy - need not work for overlap. */ test_memcpy (); /* memmove - must work on overlap. */ test_memmove (); /* mempcpy */ test_mempcpy (); /* memccpy. */ test_memccpy (); /* memset. */ test_memset (); /* bcopy. */ test_bcopy (); /* bzero. */ test_bzero (); /* bcmp - somewhat like memcmp. */ test_bcmp (); /* strndup. */ test_strndup (); /* strerror - VERY system-dependent. */ test_strerror (); if (errors == 0) { status = EXIT_SUCCESS; puts("No errors."); } else { status = EXIT_FAILURE; printf("%d errors.\n", errors); } return status;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -