C - 字符连接到字符串
C - character concatenate to string
我有以下简单的程序,可以逐个字符地读取文本文件。每次从文件中读取一个字符,都必须在 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] = '[=10=]';
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);
}
问题在于您如何重新分配() 指针。您对 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()
失败时它 returns NULL 并且您将丢失原始指针。所以你需要使用一个临时的并分配给原来的。
参见:Having dynamically allocated an array can I change its size?
2) Casting malloc()
/realloc()
etc is also dangerous.
3) 始终检查 malloc()
等的 return 值以查看内存分配是否失败。
3) 一次分配一个字符不是很有效。典型的方法是分配一个大小为 N 的缓冲区,并在 realloc()
.
时将大小加倍
没有必要将 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;
}
我有以下简单的程序,可以逐个字符地读取文本文件。每次从文件中读取一个字符,都必须在 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] = '[=10=]';
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);
}
问题在于您如何重新分配() 指针。您对 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()
失败时它 returns NULL 并且您将丢失原始指针。所以你需要使用一个临时的并分配给原来的。
参见:Having dynamically allocated an array can I change its size?
2) Casting malloc()
/realloc()
etc is also dangerous.
3) 始终检查 malloc()
等的 return 值以查看内存分配是否失败。
3) 一次分配一个字符不是很有效。典型的方法是分配一个大小为 N 的缓冲区,并在 realloc()
.
没有必要将 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;
}