scanf.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #include <stdarg.h>
  2. #include <stdio.h>
  3. #include "test_helpers.h"
  4. struct params {
  5. short sa;
  6. int ia;
  7. int ib;
  8. int ic;
  9. float fa;
  10. double da;
  11. int *ptr;
  12. char c;
  13. char string1[20];
  14. char string2[20];
  15. char string3[20];
  16. char string4[20];
  17. };
  18. void test(char* fmt_in, char* input, struct params *p, ...) {
  19. va_list args;
  20. va_start(args, p);
  21. int ret = vsscanf(input, fmt_in, args);
  22. va_end(args);
  23. printf(
  24. "%d, { sa: %hhd, ia: %d, ib: %d, ic: %d, fa: %f, da: %lf, ptr: %p, char: %c, string1: %s, string2: %s, string3: %s, string4: %s }\n",
  25. ret, p->sa, p->ia, p->ib, p->ic, p->fa, p->da, p->ptr, p->c, p->string1, p->string2, p->string3, p->string4
  26. );
  27. }
  28. int main(void) {
  29. struct params p = { .c = 'a' };
  30. test("%hd %d", "12 345", &p, &p.sa, &p.ia);
  31. test("%x %i %i", "12 0x345 010", &p, &p.ia, &p.ib, &p.ic);
  32. test("%f.%lf", "0.1.0.2", &p, &p.fa, &p.da);
  33. test("%p", "0xABCDEF", &p, &p.ptr);
  34. test("%s", "Hello World", &p, &p.string1);
  35. test("%3i", "0xFF", &p, &p.ia);
  36. test("%c%3c", "hello", &p, &p.c, &p.string1);
  37. test("test: %2i%n", "test: 0xFF", &p, &p.ia, &p.ib);
  38. test("hello world%%", "hello world%", &p);
  39. test("h%1[ae]ll%1[^a] wor%1[^\n]%[d]", "hello world", &p, &p.string1, &p.string2, &p.string3, &p.string4);
  40. test("h%1[ae]ll%1[^a] wor%1[^\n]%[d]", "halle worfdddddd", &p, &p.string1, &p.string2, &p.string3, &p.string4);
  41. test("h%1[ae]ll%1[^a] wor%1[^\n]%[d]", "halle worfdddddd", &p, &p.string1, &p.string2, &p.string3, &p.string4);
  42. test("%[^a]%[b]", "testbbbb", &p, &p.string1, &p.string2);
  43. // Scanf stolen from the url parsing in curl
  44. char protobuf[16];
  45. char slashbuf[4];
  46. char hostbuf[100];
  47. char pathbuf[100];
  48. // don't push NUL, make sure scanf does that
  49. memset(protobuf, 97, 16);
  50. memset(slashbuf, 97, 4);
  51. memset(hostbuf, 97, 100);
  52. memset(pathbuf, 97, 100);
  53. int ret = sscanf(
  54. "https://redox-os.org\0# extra garbage for nul test", "%15[^\n/:]:%3[/]%[^\n/?#]%[^\n]",
  55. &protobuf, &slashbuf, &hostbuf, &pathbuf
  56. );
  57. if (ret < 4) {
  58. *pathbuf = 0;
  59. }
  60. if (ret < 3) {
  61. *hostbuf = 0;
  62. }
  63. if (ret < 2) {
  64. *slashbuf = 0;
  65. }
  66. if (ret < 1) {
  67. *protobuf = 0;
  68. }
  69. printf("%d \"%s\" \"%s\" \"%s\" \"%s\"\n", ret, &protobuf, &slashbuf, &hostbuf, &pathbuf);
  70. }