如何避免C语言中的这种分段错误?

如何避免C语言中的这种分段错误?,c,segmentation-fault,C,Segmentation Fault,我试图使用空格将字符串与字符串分开,但不幸的是,我在C中遇到了分段错误。然而,当传递带有空格(例如“Hello World”)的字符串时,它工作正常,但当传递带有两个空格(例如“h e r”)的字符串时,它不工作 我不明白我错在哪里 #include<stdio.h> #include<string.h> char* yoda(char n1[20]) { int i,j,t=0,k=2,len,c=0; len=strlen(n1); char

我试图使用空格将字符串与字符串分开,但不幸的是,我在C中遇到了分段错误。然而,当传递带有空格(例如“Hello World”)的字符串时,它工作正常,但当传递带有两个空格(例如“h e r”)的字符串时,它不工作

我不明白我错在哪里

#include<stdio.h>
#include<string.h>
char* yoda(char n1[20])
{
    int i,j,t=0,k=2,len,c=0;
    len=strlen(n1);
    char n2[20];
    char* n3[20];
    for(i=0;i<len;i++)
    {
        if(n1[i]==' ')
        c++;
    }
    for(i=0;i<c+1;i++)
    {
        for(j=0;j<len;j++)
        {
            if(k==0)
            {
                if(n1[t+1]==' ')
                {

                    t++;
                    break;
                }
                else
                {
                    n2[j]=n1[t+1];  
                    t++;
                }
            }
            else if(n1[j]==' ')
            {
                t=j;
                k=0;
                break;  
            }
            else
            {
                k=1;
                n2[j]=n1[j];
            }
        }
        strcpy(n3[i],n2);
    }
    for(i=0;i<c+1;i++)
    {
        //for(j=0;j<len;j++)
        {
            printf("\n%s",n3[i]);
        }
    }
}
void main()
{
    int i,j,k;
    char sen[20],res[20];
    scanf("%[^\n]s",sen);
    //printf("%s",
    yoda(sen);
}
#包括
#包括
char*yoda(char n1[20])
{
int i,j,t=0,k=2,len,c=0;
len=strlen(n1);
炭n2[20];
char*n3[20];

对于(i=0;i此处由于未为
char*n3[20];
分配内存而发生分段错误。 在语句
strcpy(n3[i],n2);
中,
n3[i]
未分配给任何内存空间。您必须使用动态内存分配为
n3[i]
动态分配内存


还有你的条件,比如第一眼看到的
i:你的函数取了一个
char*
,你正在给它输入
int*
…得到一个现代编译器并打开警告。
main
的签名是
int main(void){}
strcpy(n3[i],n2);
:没有为
n3[i]
分配内存,因此seg错误。(它们没有初始化,所以指向随机位置。)使用
fgets()
读取用户输入行;或者如果坚持使用
scanf(),至少使用宽度限制(
%20[^\n]“
。哦,尾随的
s
实际上是试图与文本
s
匹配,因为转换说明符是
%[]
,句号。请检查
scanf()
返回值。其他任何东西都是在玩弄未定义的行为。另一种风格上的挑剔,因为C99不再需要在函数开始时声明所有变量;您可以在需要它们的地方声明它们(例如,
for(size\u t i=0;…)
。这通常会使代码更具可读性,并避免“未使用的变量"当您重新构造内容时会出现警告。欢迎使用堆栈溢出!请回答您的问题,以向我们展示您所做的调试类型。我希望您已经在Valgrind或类似的检查器中运行过,并使用诸如GDB之类的调试器进行过调查。请确保您也启用了一整套编译器警告。您也做了什么我告诉你,他们遗漏了什么信息?读埃里克·利珀特的。非常感谢你,下次我肯定会记得我忘记的一切。再次感谢你的建议和帮助。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *yoda(char *n1)        // modified function.
{
    int i, j, k, c = 0;
    char n2[20];
    char *n3[20];

    for (j = 0, k = 0;; j++)
    {
        if (n1[j] != ' ' && n1[j] != '\0')
        {
            n2[k++] = n1[j];
        }
        else
        {
            n2[k] = '\0';
            n3[c] = (char *)malloc(sizeof(n2)); // dynamic memory allocation
            strcpy(n3[c], n2);
            c++;
            k = 0;
        }

        if (n1[j] == '\0')
        {
            break;
        }
    }
    for (i = 0; i < c; i++)
    {
        {
            printf("\n%s", n3[i]);
        }
    }
}
int main()
{
    int i, j, k;
    char sen[20], res[20];
    scanf("%[^\n]s", sen);
    //printf("%s",
    yoda(sen);

    return 0;
}
I Love you C

I
Love
you
C