Некоторые могли бы не согласиться, но я обычно нахожу, что блок-схемы обычно не очень ценны.
В принципе, у вас есть два способа сделать это: вы можете создать копию исходной строки, минус все '\ t'
и '\ n'
символов, или вы можете удалить строку «на месте». Однако я готов поспорить, что первый вариант будет быстрее, и обещаю, что он будет безопаснее.
Итак, мы создадим функцию:
char *strip(const char *str, const char *d);
Мы хотим использовать strlen ()
и malloc ()
для выделения нового буфера char *
того же размера, что и наш буфер str
. Затем мы просматриваем str
посимвольно. Если символ не содержится в d
, мы копируем его в наш новый буфер. Мы можем использовать что-то вроде strchr ()
, чтобы увидеть, есть ли каждый символ в строке d
. Как только мы закончили, у нас есть новый буфер с содержимым нашего старого буфера минус символы в строке d
, поэтому мы просто возвращаем его. Я не буду приводить вам образец кода, потому что это может быть домашнее задание, но вот пример использования, чтобы показать вам, как он решает вашу проблему:
char *string = "some\n text\t to strip";
char *stripped = strip(string, "\t\n");
Это работает в моих быстрых и грязных тестах. Есть ли это на месте:
#include <stdio.h>
void strip(char *s) {
char *p2 = s;
while(*s != '\0') {
if(*s != '\t' && *s != '\n') {
*p2++ = *s++;
} else {
++s;
}
}
*p2 = '\0';
}
int main() {
char buf[] = "this\t is\n a\t test\n test";
strip(buf);
printf("%s\n", buf);
}
И чтобы успокоить Криса, вот версия, которая помещает результат в новый буфер malloc
ed и возвращает его (таким образом, он будет работать с литералами). Вам нужно будет освободить
результат.
char *strip_copy(const char *s) {
char *p = malloc(strlen(s) + 1);
if(p) {
char *p2 = p;
while(*s != '\0') {
if(*s != '\t' && *s != '\n') {
*p2++ = *s++;
} else {
++s;
}
}
*p2 = '\0';
}
return p;
}
Если вы хотите заменить \ n или \ t с чем-то еще , вы можете использовать функцию strstr (). Он возвращает указатель на первое место в функции, имеющей определенную строку. Например:
// Find the first "\n".
char new_char = 't';
char* pFirstN = strstr(szMyString, "\n");
*pFirstN = new_char;
Вы можете запустить это в цикле, чтобы найти все \ n и \ t.
Если вы хотите «разделить» их, т.е. удалить их из строки , вам нужно будет фактически использовать тот же метод, что и выше, но копировать содержимое строки «назад» каждый раз, когда вы найдете \ n или \ t, так что "this i \ ns a test" становится: "this is a test".
Вы можете сделать это с помощью memmove (не memcpy, поскольку src и dst указывают на перекрывающуюся память), примерно так:
char* temp = strstr(str, "\t");
// Remove \n.
while ((temp = strstr(str, "\n")) != NULL) {
// Len is the length of the string, from the ampersand \n, including the \n.
int len = strlen(str);
memmove(temp, temp + 1, len);
}
Вам нужно будет повторить этот цикл еще раз, чтобы удалить символы \ t.
Примечание: Оба эти метода работают на месте. Это может быть небезопасно! (подробности читайте в комментариях Эвана Терана. . Кроме того, эти методы не очень эффективны, хотя они действительно используют библиотечную функцию для некоторой части кода вместо того, чтобы накатывать ваш собственный.
вам нужно будет фактически использовать тот же метод, что и выше, но копировать содержимое строки "назад" каждый раз, когда вы найдете \ n или \ t, так что "this i \ ns a test" становится: "this is a test ".Вы можете сделать это с помощью memmove (не memcpy, поскольку src и dst указывают на перекрывающуюся память), например:
char* temp = strstr(str, "\t");
// Remove \n.
while ((temp = strstr(str, "\n")) != NULL) {
// Len is the length of the string, from the ampersand \n, including the \n.
int len = strlen(str);
memmove(temp, temp + 1, len);
}
Вам нужно будет повторить этот цикл еще раз, чтобы удалить \ t.
Примечание: Оба эти метода работают на месте. Это может быть небезопасно! (подробности читайте в комментариях Эвана Терана. . Кроме того, эти методы не очень эффективны, хотя они действительно используют библиотечную функцию для некоторой части кода вместо того, чтобы накатывать ваш собственный.
вам нужно будет фактически использовать тот же метод, что и выше, но копировать содержимое строки "назад" каждый раз, когда вы найдете \ n или \ t, так что "this i \ ns a test" становится: "this is a test ".Вы можете сделать это с помощью memmove (не memcpy, поскольку src и dst указывают на перекрывающуюся память), например:
char* temp = strstr(str, "\t");
// Remove \n.
while ((temp = strstr(str, "\n")) != NULL) {
// Len is the length of the string, from the ampersand \n, including the \n.
int len = strlen(str);
memmove(temp, temp + 1, len);
}
Вам нужно будет повторить этот цикл еще раз, чтобы удалить \ t.
Примечание: Оба эти метода работают на месте. Это может быть небезопасно! (подробности читайте в комментариях Эвана Терана. . Кроме того, эти методы не очень эффективны, хотя они действительно используют библиотечную функцию для некоторой части кода вместо того, чтобы накатывать ваш собственный.
This is a c string function that will find any character in accept
and return a pointer to that position or NULL if it is not found.
#include <string.h>
char *strpbrk(const char *s, const char *accept);
Example:
char search[] = "a string with \t and \n";
char *first_occ = strpbrk( search, "\t\n" );
first_occ
will point to the \t, or the 15 character in search
. You can replace then call again to loop through until all have been replaced.
I like to make the standard library do as much of the work as possible, so I would use something similar to Evan's solution but with strspn()
and strcspn()
.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SPACE " \t\r\n"
static void strip(char *s);
static char *strip_copy(char const *s);
int main(int ac, char **av)
{
char s[] = "this\t is\n a\t test\n test";
char *s1 = strip_copy(s);
strip(s);
printf("%s\n%s\n", s, s1);
return 0;
}
static void strip(char *s)
{
char *p = s;
int n;
while (*s)
{
n = strcspn(s, SPACE);
strncpy(p, s, n);
p += n;
s += n + strspn(s+n, SPACE);
}
*p = 0;
}
static char *strip_copy(char const *s)
{
char *buf = malloc(1 + strlen(s));
if (buf)
{
char *p = buf;
char const *q;
int n;
for (q = s; *q; q += n + strspn(q+n, SPACE))
{
n = strcspn(q, SPACE);
strncpy(p, q, n);
p += n;
}
*p++ = '\0';
buf = realloc(buf, p - buf);
}
return buf;
}