【问题标题】:Why character pointer is getting assigned just a character, while a string is supposed to get assigned to it?为什么字符指针只分配一个字符,而字符串应该分配给它?
【发布时间】:2016-06-11 13:24:04
【问题描述】:

字符串包含由空格分隔的三个部分。前两部分是字符串,第三部分是整数。

以下程序的输出让我感到惊讶。

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

void split(char *ch,char **part1,char **part2,int *num){
    int length=strlen(ch), *lc1,*lc2;
    int i=0,j=0;
    printf("value of length is %d\n",length);

    printf("this function recieved %s for splitting into pieces\n",ch);

    lc1=(char *)malloc(length*sizeof(char));
    lc2=(char *)malloc(length*sizeof(char));

    while(ch[i]!=' '){
        lc1[i]=ch[i];
        printf("\nin loop with lc1[i] = %c and ch[i] =  %c",lc1[i],ch[i]);
        i++;
    }
    lc1[i]='\0';
    i++;
    while(ch[i]!=' '){
        lc2[j]=ch[i];
        printf("\nin loop with lc2[j] = %c and ch[i] =  %c",lc2[j],ch[i]);
        j++;
        i++;
    }
    lc2[j]='\0';
    i++;
    *num=atoi(&ch[i]);

    *part1=lc1;
    *part2=lc2;

    printf("\nsplit results are:\n");
    printf("part1=%s and part2=%s and num=%d and lc1=%s lc2=%s    //this is surprising me",*part1,*part2,*num,lc1,lc2);

}

int main()
{
    int N,i,j,n,*numArray,count=0;
    char **arr,*part1,*part2,*token;
    scanf("%d",&N);
    arr=malloc(N*sizeof **arr);
    numArray=malloc(N*sizeof *numArray);
    for(i=0;i<N;i++){
    arr[i]=(char *)malloc(50*sizeof(char));
    }

    for(i=0;i<N;i++){
        printf("plz enter %d th :",i);
        scanf(" ");
        gets(&arr[i][0]);
    }

    for(i=0;i<N;i++){
        printf("%s",arr[i]);
    }

    for(i=0;i<N;i++){
    /*token=strtok(arr[i]," ");
    part1=token;
    token=strtok(NULL," ");
    part2=token;
    token=strtok(NULL," ");
    n=atoi(token);*/
        split(arr[i],&part1,&part2,&n);
    //some logic to use part1 and part2 of the sentence
}
return 0;

}

我提供的输入如下:

1
abcd efgh 2

输入的第一行包含我要继续的句子数。 我得到的输出如下:

plz enter 0 th :abcd efgh 2value of length is 11
this function recieved abcd efgh 2 for splitting into pieces

in loop with lc1[i] = a and ch[i] =  a
in loop with lc1[i] = b and ch[i] =  b
in loop with lc1[i] = c and ch[i] =  c
in loop with lc1[i] = d and ch[i] =  d
in loop with lc2[j] = e and ch[i] =  e
in loop with lc2[j] = f and ch[i] =  f
in loop with lc2[j] = g and ch[i] =  g
in loop with lc2[j] = h and ch[i] =  h
split results are:
part1=a and part2=e and num=2 and lc1=a lc2=e    //this is surprising me
Success time: 0 memory: 2296 signal:0
plz enter 0 th :abcd efgh 2value of length is 11
this function recieved abcd efgh 2 for splitting into pieces

in loop with lc1[i] = a and ch[i] =  a
in loop with lc1[i] = b and ch[i] =  b
in loop with lc1[i] = c and ch[i] =  c
in loop with lc1[i] = d and ch[i] =  d
in loop with lc2[j] = e and ch[i] =  e
in loop with lc2[j] = f and ch[i] =  f
in loop with lc2[j] = g and ch[i] =  g
in loop with lc2[j] = h and ch[i] =  h
split results are:
part1=a and part2=e and num=2 and lc1=a lc2=e    //this is surprising me

虽然 split() 中的循环函数已成功执行字符串中的所有字符,但我只在 part1(也在 lc1 中)和 part2(也在 lc2 中)中得到一个字符。这个输出的原因是什么?

【问题讨论】:

  • 不要投射malloc()sizeof (char) 定义为 1。不要使用gets。不要使用scanf 进行用户输入。
  • arr=malloc(N*sizeof **arr); -->> arr=malloc(N*sizeof *arr);(也有style:尝试添加一些空格,并在可以的地方用for()循环替换while()循环)
  • lc1/lc2 周围有一些类型错误。你的编译器不会警告你这些吗? (具体来说,它们被声明为 int *,但初始化/使用时就像它们是 char *。)
  • @melpomene 你能建议其他东西代替 scanf 来接受用户的输入吗?
  • fgets() 会是一个不错的@gj1103

标签: c string pointers split


【解决方案1】:

这一行是错误的:

arr=malloc(N*sizeof **arr);

应该是:

arr=malloc(N*sizeof *arr);

**arr 是一个char,所以它只为N 字节分配空间,但你需要为N 指针分配空间,这是4 个字节。所以你没有分配足够的空间,然后你在数组边界之外写,导致未定义的行为。

DEMO

【讨论】:

  • 错误是由于 *lc1,*lc2;被声明为 int... 但我无法弄清楚为什么声明 *lc1 和 *lc2 会发生什么,以及为什么它没有给出错误...
  • 当我回答问题时,它们被声明为char *。您在我发布答案后编辑了问题。
  • 说来话长……最初它是 int……然后我认为这是一个错字……所以我把它变成了字符……然后我意识到代码的行为出乎意料只是......所以我恢复了问题的变化...... melpomene(在 cmets 中)帮助我理解了这个错误...... @Barmar 抱歉......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多