在C中,意外字符被添加到字符串末尾
在我的代码中,当我通过函数发送字符数组时,会出现一个随机字符,如下所示:在C中,意外字符被添加到字符串末尾,c,C,在我的代码中,当我通过函数发送字符数组时,会出现一个随机字符,如下所示: struct TokenizerT_ { //Defintion of the struct char * sep; char * toks; }; TokenizerT *TKCreate(char *separators, char *ts) { TokenizerT * inu = malloc(sizeof(*inu)); inu->toks = malloc(sizeof(char)); /
struct TokenizerT_ { //Defintion of the struct
char * sep;
char * toks;
};
TokenizerT *TKCreate(char *separators, char *ts) {
TokenizerT * inu = malloc(sizeof(*inu));
inu->toks = malloc(sizeof(char)); //Initialize char array that will store the tokens
strcpy(inu->toks, hr);
return inu;
}
.......
best = "sein";
printf("%s\n", best);
char * rondo = malloc(sizeof(char));
printf("%s\n", rondo);
TokenizerT * Ray = TKCreate(copy, rondo); /
printf("%s\n", Ray->toks);
对于最后一位,打印出的值如下所示:
sein
sein
sein?
为什么会出现问号?这通常是一个随机字符,并不总是问号
Edit: Full code, really desperate
struct TokenizerT_ { //Defintion of the struct
char * sep;
char * toks;
};
char nulines[10] = "ntvbrfa\\\""; //for the arguments with backslashes
char resp[37] = "0x0a0x090x0b0x080x0d0x0c0x070x5c0x22";
typedef struct TokenizerT_ TokenizerT;
TokenizerT *TKCreate(char *separators, char *ts) {
if (ts==NULL) { //If there are no tokens to be parsed (empty entry)
return NULL;
}int lim = 1;
char yr[strlen(separators)]; //Initializes delimitors
yr[0] = *separators;
if(strlen(separators)>0){
int h =1;
char zmp = *(separators+h);
for(h=1; h<strlen(separators); h++){
zmp = *(separators+h);
int z=0;
for (z=0; z<lim; z++) {
if (zmp==yr[z]) {
z=-1;
break;
}
}
if(z>-1){
yr[lim] = zmp;
lim++;}
else{
continue;
} //yr is local variable that contains delimitors
}}
TokenizerT * inu = malloc(sizeof(*inu)); //Creates TokenizerT
inu->sep = malloc((int)strlen(yr)*sizeof(char));
strcpy(inu->sep, yr);
char hr [strlen(ts)];
lim = 0; int q = 0; int wy=0;
for(q=0; q<strlen(ts); q++){
if(ts[q]=='\\'){
q++;
for(wy = 0; wy<strlen(nulines); wy++){
if (nulines[wy]==ts[q]) {
hr[lim] = '['; hr[++lim] = '0'; hr[++lim] = 'x'; hr[++lim] = resp[wy*4+2];
hr[++lim] = resp[wy*4+3];
hr[++lim] = ']'; lim++;
break;
}
}
continue;
}
else{
hr[lim] = ts[q];
lim++;
}
}
inu->toks = (char *)malloc(sizeof(char) * strlen(hr) + 1);
strcpy(inu->toks, hr); //Makes copy
return inu;
}
void TKDestroy(TokenizerT *tk) {
free(tk->toks); //Free Memory associated with the token char array
free(tk->sep); //Free Memory associated with the delimitor char array
free(tk); //Free Memory associated with the tokenizer
}
char *TKGetNextToken(TokenizerT *tk) {
char * stream = tk->toks;
char * dels = tk->sep;
/*The following two lines intialize the char array to be printed
as well as the integers to be used in the various loops*/
char * temps = malloc(sizeof(char)); int g = 0;
int z = 0, x= 0, len = 0;
if (strlen(dels)==0) {
return stream;
}
for(z = 0; z<strlen(stream); z++){
char b = *(stream+z);
for(x = 0; x<strlen(dels); x++){
len = (int)strlen(temps);
char c = *(dels+x);
if(c==b){ //Here, the current character is a delimitor
g = -1;
break;
}
}
if (g==-1) { //If delimitor, then return the current token
return temps;
}
*(temps+len) = b;
}
len = (int)strlen(temps);
*(temps+len) = '\0'; //Returns the string with the null character ending it
return temps;
}
void TKN(TokenizerT * tin, int sum){
char * tmp = TKGetNextToken(tin);
char * copy = malloc(sizeof(char));
strcpy(copy, tin->sep);
int difference = (int)strlen(tmp)+1;
sum = sum-difference;
char * best = malloc(sizeof(char));
strcpy(best, tin->toks + difference);
if((int)strlen(tmp)>0){
printf("%s\n", tmp);
}
TKDestroy(tin);
tin = TKCreate(copy, best);
while(sum>0){
tmp = TKGetNextToken(tin);
if((int)strlen(tmp)>0){
printf("%s\n", tmp);
}
difference = (int)strlen(tmp)+1;
sum = sum-difference;
free(best);
best = malloc(sizeof(char));
strcpy(best, tin->toks + difference);
TKDestroy(tin);
tin = TKCreate(copy, best);
}
free(copy);
free(best);
free(tmp);
TKDestroy(tin); //Freeing up memory associated with the Tokenizer
return;
}
int main(int argc, char **argv) {
if(argc<2){
printf("%s\n", "Not enough arguments");
return 0;
}
else if(argc>3){
printf("%s\n", "Too many arguments");
return 0;
}
else{
char * arr = argv[1]; //Represents delimitors
char * y = argv[2]; //Represents string to be tokenized
TokenizerT * jer = TKCreate(arr, y); //Create and initialize tokenizer
//printf("%s\n", jer->toks);
TKN(jer, (int)strlen(jer->toks));
}
return 0;
}
Edit:完整的代码,真的很绝望
struct TokenizerT{//结构的定义
char*sep;
char*toks;
};
char numlines[10]=“ntvbrfa\\\”“;//用于带反斜杠的参数
字符响应[37]=“0x0A0X090x0B0X080x0D00C0C0070x5C0X22”;
typedef-struct-TokenizerT_u0;TokenizerT;
TokenizerT*TKCreate(字符*分隔符,字符*ts){
if(ts==NULL){//如果没有要分析的令牌(空条目)
返回NULL;
}int lim=1;
char yr[strlen(分隔符)];//初始化定界符
yr[0]=*分离器;
如果(strlen(分离器)>0){
int h=1;
char zmp=*(分离器+h);
对于(h=1;hsep=malloc((int)strlen(yr)*sizeof(char));
strcpy(每年9月至9月);
char-hr[strlen(ts)];
lim=0;int q=0;int wy=0;
对于(q=0;qtoks,hr);//复制
返回inu;
}
无效TKDestroy(TokenizerT*tk){
free(tk->toks);//释放与令牌字符数组关联的内存
free(tk->sep);//释放与定界符或字符数组关联的内存
空闲(tk);//与标记器关联的空闲内存
}
字符*TKGetNextToken(标记化字符*tk){
char*stream=tk->toks;
char*dels=tk->sep;
/*以下两行初始化要打印的字符数组
以及各种循环中使用的整数*/
char*temps=malloc(sizeof(char));int g=0;
intz=0,x=0,len=0;
如果(strlen(dels)==0{
回流;
}
对于(z=0;ztoks+差值);
如果((int)strlen(tmp)>0{
printf(“%s\n”,tmp);
}
TKDestroy(锡);
tin=TKCreate(复制,最佳);
而(总和>0){
tmp=TKGetNextToken(锡);
如果((int)strlen(tmp)>0{
printf(“%s\n”,tmp);
}
差异=(int)strlen(tmp)+1;
和=和差;
免费(最好);
最佳=malloc(sizeof(char));
strcpy(最佳,tin->toks+差异);
TKDestroy(锡);
tin=TKCreate(复制,最佳);
}
免费(副本);
免费(最好);
免费(tmp);
TKDestroy(tin);//释放与标记器关联的内存
回来
}
int main(int argc,字符**argv){
如果(argc3){
printf(“%s\n”,“参数太多”);
返回0;
}
否则{
char*arr=argv[1];//表示定界符
char*y=argv[2];//表示要标记化的字符串
TokenizerT*jer=TKCreate(arr,y);//创建和初始化标记器
//printf(“%s\n”,jer->toks);
TKN(jer,(int)strlen(jer->toks));
}
返回0;
}
在大多数malloc
中,您不仅仅为一个字符分配:
malloc(sizeof(char))
虽然你应该写:
malloc(sizeof(char) * n + 1)
<> > <代码> n<代码>是您想要的字符串长度,+1是终止代码<代码> null >代码>字符。您看到的是随机字符,因为C和C++都使用<代码> null <代码>字符作为字符串数据类型的终止,并且不正确分配,它开始读取直到它到达代码> null < /C> >
struct TokenizerT_ { //Defintion of the struct
char * sep;
char * toks;
};
char nulines[10] = "ntvbrfa\\\""; //for the arguments with backslashes
char resp[37] = "0x0a0x090x0b0x080x0d0x0c0x070x5c0x22";
typedef struct TokenizerT_ TokenizerT;
TokenizerT *TKCreate(char *separators, char *ts) {
if (ts==NULL) { //If there are no tokens to be parsed (empty entry)
return NULL;
}int lim = 1;
char yr[strlen(separators)]; //Initializes delimitors
yr[0] = *separators;
if(strlen(separators)>0){
int h =1;
char zmp = *(separators+h);
for(h=1; h<strlen(separators); h++){
zmp = *(separators+h);
int z=0;
for (z=0; z<lim; z++) {
if (zmp==yr[z]) {
z=-1;
break;
}
}
if(z>-1){
yr[lim] = zmp;
lim++;}
else{
continue;
} //yr is local variable that contains delimitors
}}
TokenizerT * inu = (TokenizerT *)malloc(sizeof(*inu)); //Creates TokenizerT
inu->sep = (char *)malloc((int)strlen(yr)*sizeof(char));
strcpy(inu->sep, yr);
char hr [strlen(ts)];
lim = 0; int q = 0; int wy=0;
for(q=0; q<strlen(ts); q++){
if(ts[q]=='\\'){
q++;
for(wy = 0; wy<strlen(nulines); wy++){
if (nulines[wy]==ts[q]) {
hr[lim] = '['; hr[++lim] = '0'; hr[++lim] = 'x'; hr[++lim] = resp[wy*4+2];
hr[++lim] = resp[wy*4+3];
hr[++lim] = ']'; lim++;
break;
}
}
continue;
}
else{
hr[lim] = ts[q];
lim++;
}
}
inu->toks = (char *)malloc(sizeof(char) * strlen(hr) + 1);
strcpy(inu->toks, hr); //Makes copy
return inu;
}
void TKDestroy(TokenizerT *tk) {
free(tk->toks); //Free Memory associated with the token char array
free(tk->sep); //Free Memory associated with the delimitor char array
free(tk); //Free Memory associated with the tokenizer
}
char *TKGetNextToken(TokenizerT *tk) {
char * stream = tk->toks;
char * dels = tk->sep;
/*The following two lines intialize the char array to be printed
as well as the integers to be used in the various loops*/
char * temps = (char *)malloc(sizeof(char)); int g = 0;
int z = 0, x= 0, len = 0;
if (strlen(dels)==0) {
return stream;
}
for(z = 0; z<strlen(stream); z++){
char b = *(stream+z);
for(x = 0; x<strlen(dels); x++){
len = (int)strlen(temps);
char c = *(dels+x);
if(c==b){ //Here, the current character is a delimitor
g = -1;
break;
}
}
if (g==-1) { //If delimitor, then return the current token
return temps;
}
*(temps+len) = b;
}
len = (int)strlen(temps);
*(temps+len) = '\0'; //Returns the string with the null character ending it
return temps;
}
void TKN(TokenizerT * tin, int sum){
char * tmp = TKGetNextToken(tin);
char * copy = (char *)malloc(sizeof(char));
strcpy(copy, tin->sep);
int difference = (int)strlen(tmp)+1;
sum = sum-difference;
char * best = (char *)malloc(sizeof(char));
strcpy(best, tin->toks + difference);
if((int)strlen(tmp)>0){
printf("%s\n", tmp);
}
TKDestroy(tin);
tin = TKCreate(copy, best);
while(sum>0){
tmp = TKGetNextToken(tin);
if((int)strlen(tmp)>0){
printf("%s\n", tmp);
}
difference = (int)strlen(tmp)+1;
sum = sum-difference;
free(best);
best = (char *)malloc(sizeof(char));
strcpy(best, tin->toks + difference);
TKDestroy(tin);
tin = TKCreate(copy, best);
}
free(copy);
free(best);
free(tmp);
TKDestroy(tin); //Freeing up memory associated with the Tokenizer
return;
}
int main(int argc, char **argv) {
if(argc<2){
printf("%s\n", "Not enough arguments");
return 0;
}
else if(argc>3){
printf("%s\n", "Too many arguments");
return 0;
}
else{
char * arr = argv[1]; //Represents delimitors
char * y = argv[2]; //Represents string to be tokenized
TokenizerT * jer = TKCreate(arr, y); //Create and initialize tokenizer
//printf("%s\n", jer->toks);
TKN(jer, (int)strlen(jer->toks));
}
return 0;
}
struct-TokenizerT{//结构的定义
char*sep;
char*toks;
};
char numlines[10]=“ntvbrfa\\\”“;//用于带反斜杠的参数
字符响应[37]=“0x0A0X090x0B0X080x0D00C0C0070x5C0X22”;
typedef-struct-TokenizerT_u0;TokenizerT;
TokenizerT*TKCreate(字符*分隔符,字符*ts){
if(ts==NULL){//如果没有要分析的令牌(空条目)
返回NULL;
}int lim=1;
char yr[strlen(分隔符)];//初始化定界符
yr[0]=*分离器;
如果(strlen(分离器)>0){
int h=1;
char zmp=*(分离器+h);
对于(h=1;hsep=(char*)malloc((int)strlen(yr)*sizeof(char));
strcpy(每年9月至9月);
char-hr[strlen(ts)];
lim=0;int q=0;int wy=0;
对于(q=0;qtoks,hr);//复制
返回inu;
}
无效TKDestroy(TokenizerT*tk){
free(tk->toks);//释放与令牌字符数组关联的内存
free(tk->sep);//释放与定界符或字符数组关联的内存
空闲(tk);//与标记器关联的空闲内存
}
字符*TKGetNextToken(标记化字符*tk){
char*stream=tk->toks;
char*dels=tk->sep;
/*以下两行初始化要打印的字符数组
以及各种循环中使用的整数*/
char*temps=(char*)malloc(sizeof(char));int g=0;
intz=0,x=0,len=0;
如果(strlen(dels)==0){
回流;
}
对于(z=0;ztoks+差值);
如果((int)strlen(tmp)>0){
printf(“%s\n”,tmp);
}
TKDestroy(锡);
tin=TKCreate(复制,最佳);
而(总和>0){
tmp=TKGetNextToken(锡);
如果((int)strlen(tmp)>0){
printf(“%s\n”,tmp);
}
差异=(int)strlen(tmp)+1;
和=和差;
免费(最好);
最佳=(char*)malloc(sizeof(char));
strcpy(最佳,tin->toks+差异);
TKDestroy(锡);
tin=TKCreate(复制,最佳);
}
免费(副本);
免费(最好);
免费(tmp);
TKDestroy(tin);//释放与标记器关联的内存
回来
}
int main(int argc,字符**argv){
如果(argc3){
printf(“%s\n”,“参数太多”);
返回0;
}
否则{
char*arr=argv[1];//表示定界符
char*y=argv[2];//表示要标记化的字符串
TokenizerT*jer=TKCreate(arr,y);//创建和初始化标记器
//printf(“%s\n”,jer->toks);
TKN(jer,(int)strlen(jer->toks));
}
返回0;
}
是一种条件。这就是你正在做的: 空闲存储(堆)->分配大小为
char
的内存(通常为1字节)
char * rondo = malloc(sizeof(char));
printf("%s\n", rondo);
char * rondo = malloc(sizeof(char));
*rondo = 'K';
printf("%c\n",*rondo);
char * rondo = malloc(sizeof(char)*no_of_characters_in_string+1);