简体   繁体   English

如何将字符串附加到字符串中,在C中动态分配内存?

[英]how can I append a char to a string allocating memory dynamically in C?

I wrote this code, but inserts garbage in the start of string: 我写了这段代码,但是在字符串的开头插入了垃圾:

void append(char *s, char c) {
    int len = strlen(s);
    s[len] = c;
    s[len + 1] = '\0';
}

int main(void) {
    char c, *s;
    int i = 0;
    s = malloc(sizeof(char));
    while ((c = getchar()) != '\n') {
        i++;
        s = realloc(s, i * sizeof(char));
        append(s, c);
    }   
    printf("\n%s",s);   
}

How can I do it? 我该怎么做?

There are multiple problems in your code: 您的代码中存在多个问题:

  • you iterate until you read a newline ( '\\n' ) from the standard input stream. 迭代直到从标准输入流中读取换行符( '\\n' )。 This will cause an endless loop if the end of file occurs before you read a newline, which would happen if you redirect standard input from an empty file. 如果在读取换行符之前发生文件结尾,则会导致无限循环,如果从空文件重定向标准输入,则会发生这种情况。
  • c should be defined as int so you can test for EOF properly. c应定义为int以便您可以正确测试EOF
  • s should be null terminated at all times, you must set the first byte to '\\0' after malloc() as this function does not initialize the memory it allocates. s应该始终以null结尾,你必须在malloc()之后将第一个字节设置为'\\0' ,因为这个函数没有初始化它分配的内存。
  • i should be initialized to 1 so the first realloc() extends the array by 1 etc. As coded, your array is one byte too short to accommodate the extra character. i应该初始化为1所以第一个realloc()将数组扩展为1等。编码后,你的数组是一个太短的字节,无法容纳额外的字符。
  • you should check for memory allocation failure. 你应该检查内存分配失败。
  • for good style, you should free the allocated memory before exiting the program 为了好的风格,你应该在退出程序之前释放分配的内存
  • main() should return an int , preferably 0 for success. main()应该返回一个int ,最好是0才能成功。

Here is a corrected version: 这是一个更正版本:

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

/* append a character to a string, assuming s points to an array with enough space */
void append(char *s, char c) {
    size_t len = strlen(s);
    s[len] = c;
    s[len + 1] = '\0';
}

int main(void) {
    int c;
    char *s;
    size_t i = 1;
    s = malloc(i * sizeof(char));
    if (s == NULL) {
        printf("memory allocation failure\n");
        return 1;
    }
    *s = '\0';
    while ((c = getchar()) != EOF && c != '\n') {
        i++;
        s = realloc(s, i * sizeof(char));
        if (s == NULL) {
            printf("memory allocation failure\n");
            return 1;
        }
        append(s, c);
    }
    printf("%s\n", s);
    free(s);
    return 0;
}

when you call strlen it searches for a '\\0' char to end the string. 当你调用strlen它会搜索'\\0'字符来结束字符串。 You don't have this char inside your string to the behavior of strlen is unpredictable. 你的字符串中没有这个字符,因为strlen的行为是不可预测的。 Your append function is acually good. 你的append功能非常好。 Also, a minor thing, you need to add return 0; 另外,一件小事,你需要添加return 0; to your main function. 到你的主要功能。 And i should start from 1 instead if 0. Here is how it should look: 如果是0, i应该从1开始。以下是它的外观:

int main(void){
   char *s;
   size_t i = 1;
   s = malloc (i * sizeof(char));//Just for fun. The i is not needed.
   if(s == NULL) {
   fprintf(stderr, "Coul'd not allocate enough memory");
   return 1;
   }
   s[0] = '\0';
   for(char c = getchar(); c != '\n' && c != EOF; c = getchar()) {//it is not needed in this case to store the result as an int.
      i++;
      s = realloc (s,i * sizeof(char) );
      if(s == NULL) {
             fprintf(stderr, "Coul'd not allocate enough memory");
             return 1;
      }
      append (s,c);
    }   
printf("%s\n",s);   
return 0;
}

Thanks for the comments that helped me improve the code (and for my english). 感谢您帮助我改进代码(以及我的英语)的评论。 I am not perfect :) 我并不完美 :)

The inner realloc needs to allocate one element more (for the trailing \\0 ) and you have to initialize s[0] = '\\0' before starting the loop. 内部realloc需要多分配一个元素(对于尾随\\0 ),你必须在开始循环之前初始化s[0] = '\\0'

Btw, you can replace your append by strcat() or write it like 顺便说一句,你可以用strcat()替换你的append或者像它一样写

size_t i = 0;
s = malloc(1);
/* TODO: check for s != NULL */
while ((c = getchar()) != '\n') {
        s[i] = c;
        i++;
        s = realloc(s, i + 1);
        /* TODO: check for s != NULL */
}
s[i] = '\0';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM