分离字符串时出现分段错误

时间:2016-02-13 20:07:47

标签: c char

我有一个函数用一个字符串中的空格替换制表符,如下所示:

#include <stdio.h>

char *detab(char *string) 
{
    for (int i = 0; string[i] != '\0'; i++)
        if (string[i] == '\t')
            string[i] = ' ';
    return string;
}

int main(int argc, char **argv)
{
    char *string = "\thello\thello";
    detab(string);
    printf("%s\n", string);
    return 0;
}

但是当我在"\thello\thello\t"上运行时,会产生分段错误。为什么这样做?我对C很新,所以我可能会遗漏一些微不足道的东西。

3 个答案:

答案 0 :(得分:2)

这可能是因为调用代码没有为字符串分配足够的空间。它必须始终至少分配一个大于字符串中可见字符的空格,以便为\ 0留出空间。

话虽如此,因为字符串是可变的,所以不需要返回字符串。它会在您工作时修改字符串。

以下是您的代码的工作版本:

void detab(char * myStr) 
{
    for (int i = 0; myStr[i] != '\0'; i++)
        if (myStr[i] == '\t')
            myStr[i] = ' ';
}

char theString[] = "\thello\thello\t";
printf("Before: %s", theString);
detab(theString);
printf("After: %s", theString);

另外,请记住以下内容:

char buffer[4] = "test"; //THIS IS NOT SAFE. It might work, but it will overwrite stuff it shouldn't
char buffer[5] = "test"; //This is Ok, but could be an issue if you change the length of the string being assigned.
char buffer[] = "test"; //This is preferred for string literals because if you change the size of the literal, it will automatically fit.

更新:根据您添加的主要方法,以下是您的问题:

您需要更改

char * string = "\thello\thello";

char string[] = "\thello\thello";

原因是,当您定义字符串文字并将其分配给char *时,它会驻留在内存的文本部分中,并且无法安全地修改。相反,您应该将字符串文字分配给char [](可以作为char *传递,因为它是它的实际类型)。这个语法将让编译器知道它应该在栈上分配空间并用字符串文字中的值填充它,允许它被修改。

char * joe =“blah”只是创建char *指针,并将其指向文本部分中的数据(这是不可变的)。

char joe [] =“blah”告诉编译器在堆栈上创建一个适当长度的数组,用字符串文字加载它,创建char *指针,然后将指针指向开头堆栈中的数据数组。

答案 1 :(得分:1)

这有效:

#include <stdio.h>
#include <string.h>

char *detab(char *string) 
{
    for (int i = 0; string[i] != '\0'; i++)
        if (string[i] == '\t')
            string[i] = ' ';
    return string;
}

int main ( int argc, char ** argv ) {
    char str[21] = "\thello\thello\t";

    printf( "%s\n", detab( str ) );

    return 0;
}

正如其他人所说,它可能是segfaulting,因为你正在修改一个字符串文字。使用char str[21],字符串文字将被复制到堆栈分配的str中,然后您的函数可以对其进行修改。

答案 2 :(得分:0)

你确定字符串总是以空值终止。

尝试一些腰带和牙套......

char *detab(char *string) 
{
    int s_len= strlen(string) + 1;

    for (int i = 0; string[i] != '\0'; i++)
    {
        if (string[i] == '\t')
        {    string[i] = ' '; }
        if (i == s_len) { /* failure - print some diagnostic */ return NULL; }
    }
    return string;
  }