动态C字符串问题 [英] Dynamic C String Problem

查看:61
本文介绍了动态C字符串问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

亲爱的,


使用conio实现我想创建一个动态字符串,

,其大小将在每次键盘命中后确定;在其他

字样中,我不想要求用户指定尺寸,而是

而不是让他/她打字并且在每次键盘击中后,函数

getch()确定他/她是否输入了ENTER键以结束

过程;否则,增加动态大小,或者如果后退键被击中则减少它。


现在,这是我的代码,我有

一个问题;也就是说,字符串添加了未输入的额外字符,并且通过

长字符串,它不会包含所有字符。这是我的代码和

提前谢谢:


#include< stdio.h>

#include< stdlib.h>

#include< conio2.h>


#define BACK_KEY 8

#define ENTER_KEY 13


typedef char * chptr;


int main(void){

int index = 0,x,y;

字符输入;

chptr buffer =(chptr)calloc(1,sizeof(char));

printf(" String Input = ");

do {

input = getch();

if(input!= ENTER_KEY&& input!= BACK_KEY ){

buffer [index] =输入;

buffer =(chptr)realloc(缓冲区,++索引);

printf(" ;%c",input);

}

else

if(input == ENTER_KEY)

buffer =(chptr)realloc(buffer, - index);

else

if(index 0){

buffer [index-1] =''\''';

buffer =(chptr)realloc(buffer, - index);

x = whe rex() - 1; y = wherey();

gotoxy(x,y); clreol();

}

} while(输入!= ENTER_KEY);

printf(" \ nString输出:%s \\ \\ n",buffer);

if(buffer!= NULL)free(buffer);

getch();

返回EXIT_SUCCESS;

}

Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don''t want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

For now, here is my code and I''m having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn''t hold all characters. Here is my code and
thank you in advance:

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

#define BACK_KEY 8
#define ENTER_KEY 13

typedef char * chptr;

int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));
printf("String Input =");
do{
input = getch();
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);
printf("%c", input);
}
else
if (input == ENTER_KEY)
buffer = (chptr) realloc (buffer,--index);
else
if (index 0){
buffer[index-1] = ''\0'';
buffer = (chptr) realloc (buffer, --index);
x = wherex() - 1; y = wherey();
gotoxy(x,y); clreol();
}
}while(input != ENTER_KEY);
printf("\nString Output: %s\n", buffer);
if (buffer != NULL) free(buffer);
getch();
return EXIT_SUCCESS;
}

推荐答案

coosa写道:
coosa wrote:

i想创建一个动态字符串,
i wanted to create a dynamic string,


换句话说,我不想让用户指定大小,
in other words, i don''t want to ask the user to specify the the size,



我就是这样做的:


/ * BEGIN line_to_string.c * /

#include< stdio.h>

#include< stdlib.h>

#include< limits.h>

#include< string.h>


struct list_node {

struct list_node * next;

void * data ;

};


int line_to_string(FILE * fp,char ** line,size_t * size);

void list_free(struct list_node * node,void(* free_data)(void *));

void list_fputs(FILE * stream,struct list_node * node);

struct list_node * string_node(struct list_node ** head,

struct list_node * tail,

char * data);


int main(无效)

{

struct list_node * head,* tail;

int rc;

char * buff_ptr;

size_t buff_size;

long unsigned line_count;


puts(

" \ n该程序制作并打印从标准输入输入的文本的所有行的列表\ n"

"

只需按Enter键结束,\ n

或输入任意一行字符即可继续。

);

tail = head = NULL;

line_count = 0;

buff_size = 0;

buff_ptr = NULL;

while((rc = line_to_string(stdin,& buff_ptr,& buff_size))1){

++ line_count;

tail = string_node(& head,tail,buff_ptr);

if(tail == NULL){

休息;

}

put(

" \\\
只需点击Enter键结束,\ n"

"或输入任何其他字符行继续。

);

}

switch(rc){

案例EOF:

if(buff_ptr!= NULL&& strlen(buff_ptr)0){

puts(" rc equals EOF \\\
buff_ptr中的字符串是:");

puts(buff_ptr);

++ line_count;

tail = string_node(& head,tail,buff_ptr);

}

break;

case 0:

puts(realloc返回空指针值);

if(buff_size 1){

puts(rc等于0 \ n buff_ptr中的字符串是:);

puts(buff_ptr);

++ line_count;

tail = string_node(& head,tail,buff_ptr);

}

break;

默认值:

休息;

}

if(line_count!= 0&& tail == NULL){

puts( 节点分配失败。;

puts(输入的最后一行没有进入列表:);

puts( buff_ptr);

}

free(buff_ptr);

puts(&\\;行缓冲区已被释放。\ n" );

printf("%lu lines输入了文本。\ n",line_count);

puts(它们是:\ n);

list_fputs(stdout,head);

list_free(头,免费);

puts(\ n列表已被释放。\ n);

返回0 ;

}


int line_to_string(FILE * fp,char ** line,size_t * size)

{

int rc;

void * p;

size_t count;


count = 0;

while((rc = getc(fp))!= EOF){

++ count;

if(count + 2 * size){

p = realloc(* line,count + 2);

if(p == NULL){

if(* size count){

(*行)[count] =''\''';

(*行)[count - 1] =(char)rc;

}否则{

ungetc(rc,fp);

}

count = 0;

休息;

}

* line = p;

* size = count + 2;

}

if(rc ==''\ n''){

(* line)[count - 1] ='' \\ 0'';

休息;

}

(*行)[count - 1] =(char)rc;

}

if(rc!= EOF){

rc = count INT_MAX? INT_MAX:count;

} else {

if(* size count){

(* line)[count] =''\ 0'';

}

}

返回rc;

}


void list_free(struct list_node * node,void(* free_data)(void *))

{

struct list_node * next_node;


while(node!= NULL){

next_node = node -next;

free_data(node -data);

free(节点);

node = next_node;

}

}


void list_fputs (FILE * stream,struct list_node * node)

{

while(node!= NULL){

fputs(node -data,stream) );

putc(''\ n'',stream);

node = node -next;

}

}


struct list_node * string_node(struct list_node ** head,

struct list_node * tail,

char *数据)

{

struct list_node * node;


node = malloc(sizeof * node);

如果(node!= NULL){

node -next = NULL;

node -data = malloc(strlen(data)+ 1);

if(node -data!= NULL){

if(* head == NULL){

* head = node;

} else {

tail -next = node;

}

strcpy(node -data,data);

} else {

free(node);

node = NULL;

}

}

返回节点;

}


/ * END line_to_string.c * /

-

pete

This is how I do that:

/* BEGIN line_to_string.c */

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

struct list_node {
struct list_node *next;
void *data;
};

int line_to_string(FILE *fp, char **line, size_t *size);
void list_free(struct list_node *node, void (*free_data)(void *));
void list_fputs(FILE *stream, struct list_node *node);
struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data);

int main(void)
{
struct list_node *head, *tail;
int rc;
char *buff_ptr;
size_t buff_size;
long unsigned line_count;

puts(
"\nThis program makes and prints a list of all the lines\n"
"of text entered from standard input.\n"
"Just hit the Enter key to end,\n"
"or enter any line of characters to continue."
);
tail = head = NULL;
line_count = 0;
buff_size = 0;
buff_ptr = NULL;
while ((rc = line_to_string(stdin, &buff_ptr, &buff_size)) 1) {
++line_count;
tail = string_node(&head, tail, buff_ptr);
if (tail == NULL) {
break;
}
puts(
"\nJust hit the Enter key to end,\n"
"or enter any other line of characters to continue."
);
}
switch (rc) {
case EOF:
if (buff_ptr != NULL && strlen(buff_ptr) 0) {
puts("rc equals EOF\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = string_node(&head, tail, buff_ptr);
}
break;
case 0:
puts("realloc returned a null pointer value");
if (buff_size 1) {
puts("rc equals 0\nThe string in buff_ptr is:");
puts(buff_ptr);
++line_count;
tail = string_node(&head, tail, buff_ptr);
}
break;
default:
break;
}
if (line_count != 0 && tail == NULL) {
puts("Node allocation failed.");
puts("The last line entered didn''t make it onto the list:");
puts(buff_ptr);
}
free(buff_ptr);
puts("\nThe line buffer has been freed.\n");
printf("%lu lines of text were entered.\n", line_count);
puts("They are:\n");
list_fputs(stdout, head);
list_free(head, free);
puts("\nThe list has been freed.\n");
return 0;
}

int line_to_string(FILE *fp, char **line, size_t *size)
{
int rc;
void *p;
size_t count;

count = 0;
while ((rc = getc(fp)) != EOF) {
++count;
if (count + 2 *size) {
p = realloc(*line, count + 2);
if (p == NULL) {
if (*size count) {
(*line)[count] = ''\0'';
(*line)[count - 1] = (char)rc;
} else {
ungetc(rc, fp);
}
count = 0;
break;
}
*line = p;
*size = count + 2;
}
if (rc == ''\n'') {
(*line)[count - 1] = ''\0'';
break;
}
(*line)[count - 1] = (char)rc;
}
if (rc != EOF) {
rc = count INT_MAX ? INT_MAX : count;
} else {
if (*size count) {
(*line)[count] = ''\0'';
}
}
return rc;
}

void list_free(struct list_node *node, void (*free_data)(void *))
{
struct list_node *next_node;

while (node != NULL) {
next_node = node -next;
free_data(node -data);
free(node);
node = next_node;
}
}

void list_fputs(FILE *stream, struct list_node *node)
{
while (node != NULL) {
fputs(node -data, stream);
putc(''\n'', stream);
node = node -next;
}
}

struct list_node *string_node(struct list_node **head,
struct list_node *tail,
char *data)
{
struct list_node *node;

node = malloc(sizeof *node);
if (node != NULL) {
node -next = NULL;
node -data = malloc(strlen(data) + 1);
if (node -data != NULL) {
if (*head == NULL) {
*head = node;
} else {
tail -next = node;
}
strcpy(node -data, data);
} else {
free(node);
node = NULL;
}
}
return node;
}

/* END line_to_string.c */
--
pete


coosa写道:
coosa wrote:

亲爱的,


使用conio实现我想创建一个动态字符串,

,其大小将在每次键盘命中后确定;在其他

字样中,我不想要求用户指定尺寸,而是

而不是让他/她打字并且在每次键盘击中后,函数

getch()确定他/她是否输入了ENTER键以结束

过程;否则,增加动态大小,或者如果后退键被击中则减少它。


现在,这是我的代码,我有

一个问题;也就是说,字符串添加了未输入的额外字符,并且通过

长字符串,它不会包含所有字符。这是我的代码和

提前谢谢:


#include< stdio.h>

#include< stdlib.h>

#include< conio2.h>
Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don''t want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

For now, here is my code and I''m having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn''t hold all characters. Here is my code and
thank you in advance:

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



这是一个非标准的标题,不应该在这个

新闻组中使用。

This is a non-standard header, and should not be used in this
newsgroup.


#define BACK_KEY 8

#define ENTER_KEY 13


typedef char * chptr;
#define BACK_KEY 8
#define ENTER_KEY 13

typedef char * chptr;



实际上不需要这么简单的typedef。更好的

只需在需要的地方使用''char *'。

There is really no need for such a simple typedef. Much better
to just use ''char *'' where needed.


int main(void){

int index = 0,x,y;

char输入;

chptr buffer =(chptr)calloc(1,sizeof(char));
int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));



你不应该转换从malloc和family返回的值。

另外,sizeof char的定义是1.


一次一个字节分配内存的方法

是浪费。你应该从一个足够大的缓冲区开始,以便b
保持预期的数据量。如果你需要更多空间,那么

会重新分配另一个大块,而不仅仅是一个额外的字节。还有

没有必要按字符缩小你的缓冲区。

You should not cast the value returned from malloc and family.
Also, sizeof char is by definition 1.

The approach you are taking of allocating memory a byte at a time
is wasteful. You should start out with a buffer big enough to
hold the expected amount of data. If you need more space, then
realloc another big block, not just an extra byte. There is also
no point in shrinking your buffer character by character.


printf(" String Input =");
printf("String Input =");



这不一定会出现;你应该fflush()stdout到

确保它确实。

This will not necessarily appear; you should fflush() stdout to
make sure it does.


do {

input = getch( );

if(输入!= ENTER_KEY&& input!= BACK_KEY){

buffer [index] = input;

buffer =(chptr)realloc(buffer,++ index);
do{
input = getch();
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);



index从0开始,你在这里递增。你的新内存块现在的大小为1,就像之前一样。


另外,如果realloc()失败,你会泄漏之前的内存内存通过缓冲区指向

。您需要将realloc()的返回值存储在

临时指针变量中,测试该值是否为null,如果

realloc()成功,则释放旧缓冲区。

index started out as 0, and you increment it here. Your new
block of memory now has a size of 1, just like it did before.

Also, if realloc() fails, you leak the previous memory pointed to
by buffer. You need to store the return value of realloc() in a
temporary pointer variable, test that for nullity, and if
realloc() succeeds, free the old buffer.


printf("%c",input);

}

else

if(input == ENTER_KEY)

buffer =(chptr)realloc(buffer, - index);

else

if (索引0){

buffer [index-1] =''\ 0'';

buffer =(chptr)realloc(buffer, - index);

x = wherex() - 1; y = wherey();

gotoxy(x,y); clreol();

}

} while(输入!= ENTER_KEY);

printf(" \ nString输出:%s \\ \\ n,缓冲区);
printf("%c", input);
}
else
if (input == ENTER_KEY)
buffer = (chptr) realloc (buffer,--index);
else
if (index 0){
buffer[index-1] = ''\0'';
buffer = (chptr) realloc (buffer, --index);
x = wherex() - 1; y = wherey();
gotoxy(x,y); clreol();
}
}while(input != ENTER_KEY);
printf("\nString Output: %s\n", buffer);



你永远不会用''\ 0''终止你的字符串。

You never terminated your string with a ''\0''.


if(buffer) != NULL)free(缓冲区);

getch();

返回EXIT_SUCCESS;

}
if (buffer != NULL) free(buffer);
getch();
return EXIT_SUCCESS;
}

< br $> b $ b -

Thomas M. Sommers - tm*@nj.net - AB2SB


--
Thomas M. Sommers -- tm*@nj.net -- AB2SB




TM Sommers写道:

T.M. Sommers wrote:

coosa写道:
coosa wrote:

亲爱的,


使用conio实现我想创建一个动态字符串,

,其大小将在每次键盘命中后确定;在其他

字样中,我不想要求用户指定尺寸,而是

而不是让他/她打字并且在每次键盘击中后,函数

getch()确定他/她是否输入了ENTER键以结束

过程;否则,增加动态大小,或者如果后退键被击中则减少它。


现在,这是我的代码,我有

一个问题;也就是说,字符串添加了未输入的额外字符,并且通过

长字符串,它不会包含所有字符。这是我的代码和

提前谢谢:


#include< stdio.h>

#include< stdlib.h>

#include< conio2.h>
Dear all,

Using the conio implementation i wanted to create a dynamic string,
whereby its size would be determined after each keyboard hit; in other
words, i don''t want to ask the user to specify the the size, but
rather keep him/her typing and after each keyboard hit, the function
getch() determines whether he/she entered the ENTER key to end the
process; otherwise, increases the dynamic size or also decreases it if
the back key was hit.

For now, here is my code and I''m having
an issue; namely, the string adds extra characters not inputed and by
long strings, it doesn''t hold all characters. Here is my code and
thank you in advance:

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



这是一个非标准的标题,不应该在这个

新闻组中使用。


This is a non-standard header, and should not be used in this
newsgroup.


#define BACK_KEY 8

#define ENTER_KEY 13


typedef char * chptr;
#define BACK_KEY 8
#define ENTER_KEY 13

typedef char * chptr;



实际上不需要这么简单的typedef。更好的

只需在需要的地方使用''char *'。


There is really no need for such a simple typedef. Much better
to just use ''char *'' where needed.


int main(void){

int index = 0,x,y;

char输入;

chptr buffer =(chptr)calloc(1,sizeof(char));
int main (void){
int index = 0, x, y;
char input;
chptr buffer = (chptr) calloc (1 , sizeof(char));



你不应该转换从malloc和family返回的值。

另外,sizeof char是定义1.


一次一个字节分配内存的方法

是浪费。你应该从一个足够大的缓冲区开始,以便b
保持预期的数据量。如果你需要更多空间,那么

会重新分配另一个大块,而不仅仅是一个额外的字节。还有

没有必要按字符缩小你的缓冲区。


You should not cast the value returned from malloc and family.
Also, sizeof char is by definition 1.

The approach you are taking of allocating memory a byte at a time
is wasteful. You should start out with a buffer big enough to
hold the expected amount of data. If you need more space, then
realloc another big block, not just an extra byte. There is also
no point in shrinking your buffer character by character.


printf(" String Input =");
printf("String Input =");



这不一定会出现;你应该fflush()stdout到

确保它确实。


This will not necessarily appear; you should fflush() stdout to
make sure it does.


do {

input = getch( );

if(输入!= ENTER_KEY&& input!= BACK_KEY){

buffer [index] = input;

buffer =(chptr)realloc(buffer,++ index);
do{
input = getch();
if (input != ENTER_KEY && input != BACK_KEY){
buffer[index] = input;
buffer = (chptr) realloc (buffer, ++index);



索引从0开始,你在这里增加它。您的新内存块现在的大小为1,就像之前一样。


index started out as 0, and you increment it here. Your new
block of memory now has a size of 1, just like it did before.



是吗?那么++指数呢?它是一个前缀运算符,所以它应该在分配之前增加

Is it? what about ++index? it''s a prefix operator, so it should
increment before the allocation


>

此外,如果realloc()失败,你会泄漏先前通过缓冲区指向

的内存。您需要将realloc()的返回值存储在

临时指针变量中,测试该值是否为null,如果

realloc()成功,则释放旧缓冲区。
>
Also, if realloc() fails, you leak the previous memory pointed to
by buffer. You need to store the return value of realloc() in a
temporary pointer variable, test that for nullity, and if
realloc() succeeds, free the old buffer.

printf("%c",input);

}

else

if(input == ENTER_KEY)

buffer =(chptr)realloc(buffer, - index);

else

if (索引0){

buffer [index-1] =''\ 0'';

buffer =(chptr)realloc(buffer, - index);

x = wherex() - 1; y = wherey();

gotoxy(x,y); clreol();

}

} while(输入!= ENTER_KEY);

printf(" \ nString输出:%s \\ \\ n,缓冲区);
printf("%c", input);
}
else
if (input == ENTER_KEY)
buffer = (chptr) realloc (buffer,--index);
else
if (index 0){
buffer[index-1] = ''\0'';
buffer = (chptr) realloc (buffer, --index);
x = wherex() - 1; y = wherey();
gotoxy(x,y); clreol();
}
}while(input != ENTER_KEY);
printf("\nString Output: %s\n", buffer);



你永远不会用''\ 0''终止你的字符串。


You never terminated your string with a ''\0''.


if(buffer) != NULL)free(缓冲区);

getch();

返回EXIT_SUCCESS;

}
if (buffer != NULL) free(buffer);
getch();
return EXIT_SUCCESS;
}




-

Thomas M. Sommers - tm*@nj.net - AB2SB



--
Thomas M. Sommers -- tm*@nj.net -- AB2SB


这篇关于动态C字符串问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆