fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. void reshift(const char *in, int nesting);
  6.  
  7. static void parse_include_directive(FILE *input, int nesting)
  8. {
  9. char filename[32];
  10.  
  11. // Читаем имя файла в filename, пока не встретим '>'.
  12. for (size_t i = 0; i < sizeof(filename) / sizeof(filename[0]); i++)
  13. {
  14. int c = fgetc(input);
  15. if (c == EOF)
  16. {
  17. fprintf(stderr, "unexpected EOF in include directive\n");
  18. exit(1);
  19. }
  20.  
  21. if (c == '>')
  22. {
  23. // Нашли конец имени. Используем и выходим.
  24. filename[i] = '\0';
  25. reshift(filename, nesting + 1);
  26. return;
  27. }
  28.  
  29. filename[i] = c;
  30. }
  31.  
  32. fprintf(stderr, "too long filename\n");
  33. exit(1);
  34. }
  35.  
  36. void reshift(const char *in, int nesting)
  37. {
  38. if (nesting > 5)
  39. {
  40. fprintf(stderr, "recursion too deep\n");
  41. exit(1);
  42. }
  43.  
  44. FILE *input = fopen(in, "r");
  45. if (!input)
  46. {
  47. perror("unable to open included file");
  48. exit(1);
  49. }
  50.  
  51. const char include_prefix[] = "include<";
  52.  
  53. int c;
  54. size_t prefix_pos = 0;
  55.  
  56. while ((c = fgetc(input)) != EOF)
  57. {
  58. // Если символ - начало или продолжение префикса, следующий символ
  59. // будем матчить со следующим символом префикса.
  60. if (c == include_prefix[prefix_pos])
  61. {
  62. ++prefix_pos;
  63.  
  64. // Если префикс кончился, обрабатываем имя.
  65. if (include_prefix[prefix_pos] == '\0')
  66. {
  67. // Оно само сожрет имя файла и >.
  68. parse_include_directive(input, nesting);
  69. prefix_pos = 0;
  70. }
  71. }
  72. else
  73. {
  74. // Матчили-матчили, но не сматчили. Выводим, то, что сматчилось,
  75. // если такое было.
  76. for (size_t i = 0; i < prefix_pos; i++)
  77. {
  78. putchar(include_prefix[i]);
  79. }
  80.  
  81. prefix_pos = 0;
  82.  
  83. // И не сматчившийся символ тоже выводим.
  84. putchar(c);
  85. }
  86. }
  87. }
  88.  
  89. int main(void)
  90. {
  91. reshift("input.txt", 0);
  92. }
  93.  
Runtime error #stdin #stdout #stderr 0s 2240KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
unable to open included file: No such file or directory