#c #string #char #realloc #strlen
#c #строка #обуглить #перераспределить #стрлен
Вопрос:
как бы спрашивая еще раз, я попросил сделать большую строку из маленьких. между каждой маленькой строкой мне нужно добавить»@», а между каждым словом в каждой маленькой строке мне нужно добавить » # » без пробелов в начале и в конце новой строки
У меня есть два вопроса
- как я должен определить большую строку в «main», чтобы избежать ненужных пробелов и не завалить strlen вставкой NULL
- как правильно определить новую длину ? потому что я продолжаю получать минусовые числа.
void add(char** addTo, char* str,int on) { //on ==1 for nun last string to add if (str != NULL) { while (str != NULL) { char* temp = strtok(str, " n"); if (temp != NULL) { int newlength = (strlen(*addTo) strlen(temp) 3) * sizeof(char); *addTo = (char*)realloc(*addTo, newlength); strcat(*addTo, temp); if (str != NULL) strcat(*addTo, "#"); } } if(on) strcat(*addTo, "@"); else *addTo = (char*)realloc(*addTo, strlen(*addTo)-1); } }
Комментарии:
1. Несвязанное: для меня
NULL
это указатель… если я говорю о терминаторе нулевой строки, я предпочитаю использовать''
его явно, чтобы избежать путаницы (для других и для себя).2.
NULL
это не пустая строка, это даже не строка.""
является
Ответ №1:
В вашем коде есть несколько проблем:
- функция изменяет содержимое массива, на который указывает
str
. Этот побочный эффект может иметь непредвиденные последствия и приведет к неопределенному поведению, еслиstr
указывает на строковый литерал. str
не изменяется в цикле, вызывая бесконечный цикл, если он указывает на непустую непустую строку.- в этом споре нет необходимости
on
. Значение@
должно быть вставлено перед каждой маленькой строкой, кроме первой, которую можно проверить с помощью*addTo
. - вы не проводите проверку на сбой перераспределения.
Вот модифицированная версия, которая использует lt;ctype.hgt;
для проверки все символы пробела и вызывает realloc
один раз за вызов:
#include lt;ctype.hgt; #include lt;stdio.hgt; #include lt;stdlib.hgt; #include lt;string.hgt; void add(char **addTo, const char *str, int on) { int len, newlen = 0; unsigned char c, lastc, first; char *dest; const char *p; for (p = str, lastc = ' ', first = 1; (c = *p ) != ''; lastc = c) { if (!isspace(c)) { if (isspace(lastc) amp;amp; !first) newlen ; first = 0; newlen ; } } if (newlen == 0) return; if (*addTo amp;amp; **addTo) { len = strlen(*addTo); newlen ; } dest = realloc(*addTo, len newlen 1); if (!dest) { perror("reallocation failure"); abort(); } *addTo = dest; if (len) { dest = len; *dest = '@'; } for (p = str, lastc = ' ', first = 1; (c = *p ) != ''; lastc = c) { if (!isspace(c)) { if (isspace(lastc) amp;amp; !first) *dest = '#'; first = 0; *dest = c; } } *dest = ''; }