在运行时将内存分配给字符串

时间:2018-04-07 14:03:34

标签: c realloc

我正在编写一个程序,用于计算在刺痛中出现'2'后跟'1'的情况。 我动态分配了字符串

代码是:

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

    int penalty_shoot(char* s){
        int count=0,i=0;
        while(s[i]!='\0'){
           if(s[i]=='2')
                if(s[i+1]=='1')
                    count++;
        i++;
        }
        return count;
    }

    int main() {
        int t;
        int i=0;
        scanf("%d",&t);           //t is for number of test cases.
        while(t--){
            char *str, c;
            str = (char*)malloc(1*sizeof(char));
            while(c = getc(stdin),c!='\n')
            {
                str[i] = c;
                i++;
                str=realloc(str,i*sizeof(char));
            }
            str[i] ='\0';
            printf("%s\n",str);
            printf("%d\n",penalty_shoot(str));

            free(str);
            str=NULL;
            i=0;
        }
        return 0;
    }

输入是:

3
101201212110
10101
2120

我面临两个问题:

1)我觉得动态分配工作不正常。我编写了动态分配代码,在stackoverflow上查看各种代码。 (任何人都可以提出一些改变。)

2)代码未读取'2120'作为第3个输入。 (为什么会这样?)

2 个答案:

答案 0 :(得分:2)

三个错误:

  1. 不检查EOF

    while(c = getc(stdin),c!='\n')更改为while(c=getc(stdin),c!='\n'&&c!=EOF)

  2. 重新分配错误的字节数:

    str=realloc(str,i*sizeof(char));更改为str=realloc(str,(i+1)*sizeof(char));

    在接受一个字符输入后,我们增加ii++),因此下一个字符将存储在ith位置。现在,为了将字符存储在ith位置,字符数组的长度必须为i+1。所以,我们realloci+1

      

    正如Basile所建议的那样,为了简洁起见,你   不妨这样做:

         

    str=realloc(str,(i+1)*sizeof(char));更改为str=realloc(str,i+1);

         

    为什么呢?因为sizeof char1字节

  3. 输入\n后不消耗t

    scanf("%d",&t);更改为scanf("%d ",&t);scanf("%d\n",&t);

    scanf("%d ",&t);scanf("%d\n",&t);

    他们中的任何一个都有效。你为什么问?阅读另一个SO回答here中的解释:

      

    格式字符串中的\n - 或任何空格字符 - 消耗   一个完整的(可能是空的)空白字符序列   输入。所以scanf只在遇到下一个时返回   非空白字符,或输入流的结尾。

  4. 经过测试here

答案 1 :(得分:0)

当用户输入测试时,您可以使用scanf("%d ", &t); 然后就在第二个while循环之前,哪个条件应该是c != '\n'c = getchar(); 然后确保你创建一个char变量,我称之为清除,收到0所以当你在启动你的字符串后循环时,你再次写下c = clear;并在其下c = getchar()。当你使用realloc时,请确保通过(i + 1)使其变大,因为char只有1个字节的大小。

我们创建clear变量以清除缓冲区。

它对我有用。确保一次插入所有字符串。