C - 字符连接到字符串

时间:2015-11-28 15:30:31

标签: c string realloc

我有以下简单程序,逐字符读取文本文件。每次从文件中读取一个字符时,必须在 str 的末尾开始,这是一个字符串。出于这个原因,我创建了一个名为 conc 的小函数,它接受字符,重新分配 str ,然后将字符放在字符串的末尾( str [count] ] = ch )。
在EOF字符之后,我将' \ 0' 字符添加到 str 作为字符串变量的结尾。 我的问题是为什么最后一个printf显示垃圾?有任何想法吗?? 提前谢谢。

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

void conc(char* str,char ch,int* count);

int main(int argc,char** argv)
{
   char* str = (char*)malloc(sizeof(char));
   char ch;
   int count = 0,i;
   FILE* fp = fopen("path","r");

   if(fp == NULL){
       printf("No File Found");
       return 1;
   }

   ch=fgetc(fp);
   while(ch!=EOF){
       conc(str,ch,&count);
       ch=fgetc(fp);
   }

   str[count] = '\0';
   printf("%s",str);

   free(str);

   return(0);
}

void conc(char* str,char ch,int* count){
    str[*count] = ch;
    (*count)++;
    //printf("\n%c",str[(*count)-1]);
    str = (char*)realloc(str,(*count)+1);
}

2 个答案:

答案 0 :(得分:3)

问题在于你如何realloc()指针。您对str所做的更改不会修改main()中的原始指针。您只需分配str中指针conc()的副本。您需要将指针传递给指针才能对其进行修改。

void conc(char** str,char ch,int* count){
    (*str)[*count] = ch;
    (*count)++;
    *str = realloc(*str,(*count)+1);
}

并从main()传递指向它的指针:

conc(&str,ch,&count);

更改原型以匹配:

void conc(char** str,char ch,int* count);

其他人注意到:

1)当realloc()失败时,它返回NULL,你将丢失原始指针。所以你需要使用临时文件并分配给原文。 请参阅:Having dynamically allocated an array can I change its size?

2)Casting malloc()/realloc() etc is also dangerous.

3)始终检查malloc()等的返回值,以查看内存分配是否失败。

3)一次分配一个字符不是很有效。典型的方法是在realloc()时分配大小为N的缓冲区并加倍大小。

答案 1 :(得分:0)

没有必要将count传递给您的函数,因为您(或者更确切地说,应该)将正确的零终止字符串传递给它,并且应该始终将新字符添加到其末尾。

如果您要修改str,最好从str = NULL开始。在第一次调用时,设置str以占用2个字节开始,并在每次下次调用时添加1个字符。

小心使用char ch;,然后使用while(ch!=EOF) ..!这仅在您的默认char已签名时有效。当您在输入中遇到字节0FFh时,它也会过早停止。

考虑到这些要点,我最终得到了这个:

char *conc (char *str, char ch);

int main (void)
{
   char *str = NULL;
   int ch;

   FILE* fp = fopen("path","r");

   if(fp == NULL){
       printf("No File Found");
       return 1;
   }

   ch=fgetc(fp);
   while(ch!=EOF)
   {
       str = conc (str, ch);
       ch = fgetc(fp);
   }

   printf("%s",str);

   free(str);

   return 0;
}

char *conc (char *str, char ch)
{
    int last_pos;
    if (str)
    {
        last_pos = strlen(str);
        str = realloc (str, last_pos+1);
    } else
    {
        str = malloc(2);
        last_pos = 0;
    }
    str[last_pos] = ch;
    str[last_pos+1] = 0;
    return str;
}