我正在用 C 语言制作一个非常简单的 TODOlist。
我的添加函数将 char *
作为参数。当我将它添加到我的 char **
提醒列表时,它添加了我的缓冲区的内存地址而不是字符串的值。
当我运行下面给定的源时,问题变得很明显。
如果您尝试 [a] 添加一个字符串,请说“测试”,然后发出命令 [p]rint,将打印一个“p”。
我知道这是因为我的 list[0]
持有一个指向我的缓冲区的指针,所以当缓冲区的值发生变化时,我列表中的值也会发生变化。
我的 C 生锈了,我知道 strcpy()
可能会解决这个问题?但这是通常的处理方式吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int size = 0;
int capacity = 50;
char **list;
void initList() {
list = malloc( capacity * sizeof( char * ) );
for (int i = 0; i < capacity; i++ ) {
list[i] = malloc( 256 * sizeof( char ) );
}
}
void saveReminders() {
}
void add( char *reminder ) {
list[size++] = reminder;
}
void delete( int index ) {
}
void print() {
for ( int i = 0; i < size; i++ )
printf( "%s\n", list[i] );
}
void quit() {
saveReminders();
exit( 0 );
}
void readReminders() {
}
void helpMenu() {
printf( "Enter a command:\n" );
printf( "[a]dd a reminder\n" );
printf( "[d]elete a reminder\n" );
printf( "[p]rint all reminders\n" );
printf( "[q]uit\n" );
}
void menu() {
helpMenu();
while ( 1 ) {
char buffer[64];
int index = 0;
printf( "> " );
scanf( "%s", buffer );
if ( strcmp( buffer, "a" ) == 0 ) {
printf( "Enter a reminder:\n> " );
scanf( "%s", buffer );
add( buffer );
helpMenu();
}else if ( strcmp( buffer, "d" ) == 0 ) {
printf("Remove which index?\n> " );
scanf( "%d", &index );
delete( index );
helpMenu();
}else if ( strcmp( buffer, "p" ) == 0 ) {
print();
helpMenu();
}else if ( strcmp( buffer, "q" ) == 0 ) {
quit();
}
}
}
int main( int argc, char* argv[] ) {
initList();
menu();
}
最佳答案
是的,你想对了。在您的代码中,不要分配指针本身,而是执行类似
的操作 strcpy(list[size++], reminder);
复制内容。查看man page供引用。
如果您想使用第二种方法,您也不需要为每个 list[i]
malloc()
。您可以直接使用 strdup()
而不是使用 malloc()
然后使用 strcpy()
并将返回值分配给每个 list[i]
以获得相同的结果。
也就是说,还有一些需要注意的地方
- 在使用
list[size++]
之前,确保size
小于capacity
,否则你最终会超出分配的内存,创建 undefined behavior . scanf( "%s", buffer );
应该是scanf( "%63s", buffer );
以防止任何可能的缓冲区溢出。- 在使用返回的指针之前,始终检查
malloc()
的返回值是否成功。 sizeof( char )
在 C 标准中定义为1
。将其用作乘数是多余的。
关于c - 如何按值而不是引用添加字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34410890/