forked from 131/lab0.1_letscontinue
first commit
This commit is contained in:
39
README.md
Normal file
39
README.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
## letscontinue
|
||||||
|
|
||||||
|
Копия README.md на сайте `https://timplab.syktsu.ru/131/lab0.1_letscontinue`
|
||||||
|
|
||||||
|
|
||||||
|
### Задачи
|
||||||
|
|
||||||
|
* написать программу `wcl`.
|
||||||
|
|
||||||
|
В качестве аргументов программе `wcl` передаётся один или несколько путей к файлам.
|
||||||
|
На выход печатается количество строк и имя файла (разделённые символом \t).
|
||||||
|
|
||||||
|
Примеры работы:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./wcl ./test/wiki_ci
|
||||||
|
3335 ./test/wiki_ci
|
||||||
|
|
||||||
|
$ ./wcl ./test/wiki_ci ./test/nullfile
|
||||||
|
3335 ./test/wiki_ci
|
||||||
|
0 ./test/nullfile
|
||||||
|
```
|
||||||
|
|
||||||
|
* дополнить wcl чтобы она печатала информацию о том, сколько в файле байт и слов.
|
||||||
|
|
||||||
|
* Посмотреть исходники `str.h`, `str.c`, `str_test.c`.
|
||||||
|
`str.h` -- библиотека для работы со строками.
|
||||||
|
Необходимо дописать функции в str.c чтобы все тесты из `str_test.c` завершились успешно.
|
||||||
|
|
||||||
|
## help
|
||||||
|
|
||||||
|
Для работы вам могут пригодится следующие команды и утилиты:
|
||||||
|
|
||||||
|
* malloc(3) -- функции для работы с динамической памятью
|
||||||
|
* free(3) -- функции для работы с динамической памятью
|
||||||
|
* realloc(3) -- функции для работы с динамической памятью
|
||||||
|
* memset(3) -- функция, заполняющая буфер константным значением
|
||||||
|
* memcpy(3) -- функция, копирующая данные между двумя массивами
|
||||||
|
* strlen(3) -- функция, вычисляющая длинну строки
|
||||||
57
str.c
Normal file
57
str.c
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "str.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#define INIT_SZ 20
|
||||||
|
|
||||||
|
void
|
||||||
|
str_init(str *s)
|
||||||
|
{
|
||||||
|
assert(s);
|
||||||
|
// <YOURCODE>
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
str_deinit(str *s)
|
||||||
|
{
|
||||||
|
if (s->ptr)
|
||||||
|
free(s->ptr);
|
||||||
|
s->ptr = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
str_init_data(str *s, const char *initial)
|
||||||
|
{
|
||||||
|
assert(s && initial);
|
||||||
|
// <YOURCODE>
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
str_data(str *s)
|
||||||
|
{
|
||||||
|
assert(s);
|
||||||
|
// <YOURCODE>
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
str
|
||||||
|
str_copy(str *s)
|
||||||
|
{
|
||||||
|
assert(s);
|
||||||
|
// <YOURCODE>
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
str_append(str *s, char *p)
|
||||||
|
{
|
||||||
|
// <YOURCODE>
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
str_shrink(str *s, int sz)
|
||||||
|
{
|
||||||
|
assert(s && sz >= 0);
|
||||||
|
// <YOURCODE>
|
||||||
|
}
|
||||||
35
str.h
Normal file
35
str.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Str это структура, которая хранит в памяти строки произвольной длинны
|
||||||
|
// sz -- содержит текущий размер строки (0 если строка не инициализирована или нулевого размера)
|
||||||
|
// Размер строки -- количество байт, занятое под символы (за исключением последнего нулевого байта)
|
||||||
|
// capacity содержит размер динамически инициализированного массива ptr
|
||||||
|
|
||||||
|
struct Str {
|
||||||
|
int sz;
|
||||||
|
int capacity;
|
||||||
|
char *ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Str str;
|
||||||
|
|
||||||
|
// Инициализация пустой строки
|
||||||
|
void str_init(str *s);
|
||||||
|
// Инициализация строки с данными
|
||||||
|
void str_init_data(str *s, const char *initial);
|
||||||
|
|
||||||
|
// Деинициализируем строку (освобождаем память по указателю ptr)
|
||||||
|
void str_deinit(str *s);
|
||||||
|
|
||||||
|
// Функция должна вернуть указатель на ptr
|
||||||
|
char *str_data(str *s);
|
||||||
|
|
||||||
|
//Функция создаёт и возвращает новую строку, копию s
|
||||||
|
str str_copy(str *s);
|
||||||
|
|
||||||
|
//добавляет к строке строку suffix
|
||||||
|
void str_append(str *s, char *suffix);
|
||||||
|
|
||||||
|
//уменьшает размер строки до sz байт
|
||||||
|
void str_shrink(str *s, int sz);
|
||||||
63
str_test.c
Normal file
63
str_test.c
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "str.h"
|
||||||
|
|
||||||
|
#define my_assert(cond, reason, ...) do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
printf("[-] ERROR " reason "\n", ##__VA_ARGS__); \
|
||||||
|
printf("\t%s:%d " #cond "\n", __FILE_NAME__, __LINE__); \
|
||||||
|
exit(1); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
test_it()
|
||||||
|
{
|
||||||
|
str s;
|
||||||
|
|
||||||
|
//TEST str_init
|
||||||
|
str_init(&s);
|
||||||
|
|
||||||
|
my_assert(s.sz == 0, "initial size should be 0");
|
||||||
|
my_assert(s.ptr == str_data(&s), "str_data должна вернуть то же самое что хранится в ptr поле");
|
||||||
|
str_deinit(&s);
|
||||||
|
|
||||||
|
// TEST str_init_data
|
||||||
|
str_init_data(&s, "hello");
|
||||||
|
my_assert(s.sz == strlen("hello"), "str_init_data, неправильный размер строки");
|
||||||
|
my_assert(strcmp(str_data(&s), "hello") == 0, "не правильная строка '%s' != 'hello'", str_data(&s));
|
||||||
|
|
||||||
|
// TEST str_copy
|
||||||
|
str s2;
|
||||||
|
s2 = str_copy(&s);
|
||||||
|
my_assert(s2.sz == s.sz,
|
||||||
|
"str_copy. размеры строк разные!");
|
||||||
|
my_assert(strcmp(str_data(&s), str_data(&s2)) == 0,
|
||||||
|
"str_copy получились разные строки '%s' != '%s'", str_data(&s), str_data(&s2));
|
||||||
|
my_assert(s.ptr != s2.ptr, "str_copy s.ptr и s2.ptr не должны указывать на одну строку. Указатели строк должны быть разными");
|
||||||
|
|
||||||
|
// TEST str_append
|
||||||
|
str_append(&s, " world");
|
||||||
|
my_assert(strcmp(s.ptr, "hello world") == 0, "str_append, неправильная строка %s", s.ptr);
|
||||||
|
str_append(&s, "loooooooooooooooooooooooooooooooooooooooooooooooong str");
|
||||||
|
my_assert(strcmp(s.ptr, "hello worldloooooooooooooooooooooooooooooooooooooooooooooooong str") == 0, "str_append вторая проверка, неправильная строка");
|
||||||
|
|
||||||
|
|
||||||
|
// TEST str_shrink
|
||||||
|
str_shrink(&s, 5);
|
||||||
|
my_assert(s.sz == 5, "str_shrink неправильный размер строки");
|
||||||
|
my_assert(strcmp(str_data(&s), "hello") == 0, "str_shrink не правильная строка");
|
||||||
|
|
||||||
|
printf("[+] ALL_TESTS_PASSED\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
test_it();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
40
util.c
Normal file
40
util.c
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void *
|
||||||
|
xmalloc(size_t sz)
|
||||||
|
{
|
||||||
|
void *res;
|
||||||
|
res = malloc(sz);
|
||||||
|
if (sz != 0 && res == NULL) {
|
||||||
|
perror("malloc()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
xrealloc(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
void *res;
|
||||||
|
|
||||||
|
res = realloc(ptr, size);
|
||||||
|
if (size != 0 && res == NULL) {
|
||||||
|
perror("realloc()");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
xerror(int rc, char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
|
||||||
|
exit(rc);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user