#include <stdio.h>
#include <string.h>
#include <malloc.h>
int getStr(char**);//функция ввода строк
int Amount(char* s);//функция считающая количество единиц в первом числе
char* reorg(char *, int q, int* m);//функция ввода строк
char *skipSpaces(char *); //пропуск пробелов
int check(char* s);//проверка строки
char* copyNumber(char** res, char* s, int q, int* m); //функция добавляющая или не добавляющая число в новыу строку
//основная функция программы
int main()
{
char* s = NULL; //строка источник
char* p = NULL; //строка приёмник
int flag;
int amount;
int m;
//пока не ввели конец файла работает цикл
while (1)
{
puts("Enter string to make new or CTRL+Z to exit");
flag = getStr(&s); //flag - код ошибки
if (flag == -1) //если он равен -1 - то ввели конец файла
return 0;
if (flag == -2) //если равен -2 - нехватка памяти
{
puts("Memory is out");
return 0;
}
amount = Amount(s);
printf("Amount of 1 in the first number: %d\n", amount);
printf("Source string: %s\n", s);//выводим то, что ввели
if (!check(s))
{
puts("Incorrect string. String could contain inly digits.");
free(s);
}
else
{
p = reorg(s, amount, m);//получаем неовую строку
if (p)
printf("Result string: %s \n", p);//выводим новую строку
else
puts("Result string is empty");
free(s);//очищаем память
free(p);//очищаем память
}
}
puts("That's all. Bye!");
return 0;
}
//пропуск пробелов
char* skipSpaces(char* s)
{
int k = strspn(s, " \t");
return s + k;
}
//проверка, что строка состоит из двотчных чисел
int check(char* s)
{
int k = strspn(s, "01 \t"); //подсчитали сколько символов в ходит в перечисленные
char c = *(s + k); //получили символ после них, если это нуль-байт, то строка ок, иначе - нет
return c == '\0';
}
int getStr(char** s) //получаем строку из входного потока
{
char buf[21];//считываем из входного потока строку с помощью этого буфера, кусками по 20 символов
int n;//сюда будет записываться результат scanf
int len = 0;//сюда длина результирующей строки
*s = (char *)malloc(1);//указатель на результирующую сткроу
**s = '\0';//ноль байт, пока строка имеет только конец строки
do {
n = scanf("%20[^\n]", buf);//считываем буфер
if (n < 0)
{//если ввели конец файла (ctrl+Z), то будет -1
free(*s);//очищаем память, возвращаем пустой указатель
return -1;
}
if (n > 0) {//если буфер не пустой
len += strlen(buf);//увеличиваем результирующую длину
*s = (char *)realloc(*s, len + 1);//добавляем память
if (*s)//если память выделилась
strcat(*s, buf);//копируем строку из буфера в конец нашей строки
else
{//если память не выделилась
free(*s);//очищаем память
return -2;
}
}
else
scanf("%*c");//если перенос строки, то очищаем входной поток
} while (n > 0);//пока во входном потоке есть хоть один символ
return 0;
}
char* reorg(char* s, int q, int* m){
char* p;
char* res;
if (*s == 0)
return NULL;
p = (char *)calloc(strlen(s) + 1, sizeof(char));
res = p;
while (*(s = skipSpaces(s)))
{
s = copyNumber(&p, s, q, &m);
if (p != res) {
if (m==1)
*p++ = ' ';
}
}
return (char *)realloc(res, p - res + 1);
}
int Amount(char* s){
int count = 0;
while (*s=='0' || *s==' ')
++s;
while (*s != '\0' && *s != '\t' && *s != ' ')
{
if (*s == '1')
++count;
++s;
}
return count;
}
char* copyNumber(char** res, char* s, int q, int* m){
char* next;
int count = 0, i = 0, t;
*m = 0;
while (*s == '0' || *s == ' ')
++s;
while (*s != '\0' && *s != '\t' && *s != ' ') {
if (*s == '1')
++i;
++s;
++count;
}
next = s;
t = count;
if (i == q){
*m = 1;
while (t){
--s;
--t;
}
while (count){
**res = *s;
++*res;
++s;
--count;
}
}
return next;
}