【问题标题】:C - character concatenate to stringC - 字符连接到字符串
【发布时间】:2016-03-02 13:56:44
【问题描述】:

我有以下简单的程序,可以逐个字符地读取文本文件。每次从文件中读取一个字符时,都必须放在 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);
}

【问题讨论】:

    标签: c string realloc


    【解决方案1】:

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

    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) 一次分配一个字符不是很有效。典型的方法是分配一个大小为 N 的缓冲区,并在 realloc() 时将大小翻倍。

    【讨论】:

    • 谢谢蓝月亮。我感谢您的帮助和您的时间。你的额外笔记也对我很有帮助。
    【解决方案2】:

    没有必要将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;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-09-14
      • 2014-03-31
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多