如何从C中的给定字符串中删除\ n或\ t?

时间:2009-10-03 23:54:41

标签: c string

如何在C?

中删除所有\ n和\ t的字符串

5 个答案:

答案 0 :(得分:14)

这适用于我快速而肮脏的测试。是否到位:

#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);
}

为了安抚Chris,这里是一个版本,它将首先复制并返回它(因此它将在文字上工作)。您需要free结果。

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;
}

答案 1 :(得分:4)

如果要将\ n或\ t替换为其他,可以使用函数strstr()。它返回一个指针,指向具有特定字符串的函数中的第一个位置。例如:

// Find the first "\n".
char new_char = 't';
char* pFirstN = strstr(szMyString, "\n");
*pFirstN = new_char;

你可以在一个循环中运行它来找到所有\ n和\ t的。

如果你想“剥离”它们,即从字符串中删除它们,你需要实际使用与上面相同的方法,但每次复制字符串的内容“返回”你找到\ n或\ t的时间,以便“这个测试”成为:“这是一个测试”。

你可以使用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的。

注意:这两种方法都可就地运行。 这可能不安全! (请阅读Evan Teran的评论以获取详细信息。。此外,这些方法效率不高,尽管它们对某些代码使用库函数而不是自己编写。

答案 2 :(得分:3)

基本上,您有两种方法可以执行此操作:您可以创建原始字符串的副本,减去所有'\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");

答案 3 :(得分:1)

这是一个c字符串函数,可以找到accept中的任何字符并返回指向该位置的指针,如果找不到则返回NULL。

#include <string.h>

char *strpbrk(const char *s, const char *accept);

示例:

char search[] = "a string with \t and \n";

char *first_occ = strpbrk( search, "\t\n" );

first_occ将指向\ {,或search中的15个字符。您可以替换然后再次呼叫以循环直到所有已被替换。

答案 4 :(得分:0)

我喜欢让标准库尽可能多地完成工作,所以我会使用类似于Evan的解决方案,但使用strspn()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;
}