Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何按值而非引用添加字符串_C_Arrays_String_Pointers_Strcpy - Fatal编程技术网

C 如何按值而非引用添加字符串

C 如何按值而非引用添加字符串,c,arrays,string,pointers,strcpy,C,Arrays,String,Pointers,Strcpy,我正在用C语言制作一个非常简单的TODOlist 我的add函数使用char*作为参数。当我将它添加到我的char**提醒列表时,它会添加缓冲区的内存地址,而不是字符串的值 当我运行下面给定的源代码时,问题变得很明显 如果您尝试[a]添加一个字符串,说“Test”,然后发出[p]rint命令,将打印一个“p” 我知道这是因为我的列表[0]中有一个指向我的缓冲区的指针,所以当缓冲区的值发生变化时,我列表中的值也会发生变化 我的C已经生锈了,我知道strcpy()可以解决这个问题吗?但这是通常的处理

我正在用C语言制作一个非常简单的TODOlist

我的add函数使用
char*
作为参数。当我将它添加到我的
char**
提醒列表时,它会添加缓冲区的内存地址,而不是字符串的值

当我运行下面给定的源代码时,问题变得很明显

如果您尝试[a]添加一个字符串,说“Test”,然后发出[p]rint命令,将打印一个“p”

我知道这是因为我的
列表[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();  
}
#包括
#包括
#包括
int size=0;
国际通行能力=50;
字符**列表;
void initList(){
列表=malloc(容量*sizeof(字符*);
对于(int i=0;i”);
scanf(“%s”,缓冲区);
if(strcmp(缓冲器,“a”)==0){
printf(“输入提醒:\n>”;
scanf(“%s”,缓冲区);
添加(缓冲区);
帮助菜单();
}else if(strcmp(缓冲区,“d”)==0){
printf(“删除哪个索引?\n>”;
scanf(“%d”和索引);
删除(索引);
帮助菜单();
}else if(strcmp(缓冲区,“p”)==0){
打印();
帮助菜单();
}else if(strcmp(缓冲区,“q”)==0){
退出();
}
}
}
int main(int argc,char*argv[]){
initList();
菜单();
}

是的,你认为这是对的。在代码中,不要指定指针本身,而是执行以下操作

 strcpy(list[size++], reminder);
复制内容。有关参考信息,请参阅

如果您想使用第二种方法,您也不需要为每个
列表[i]
使用
malloc()
。您可以直接使用返回值并将其分配给每个
列表[i]
,而不是使用
malloc()
然后再使用
strcpy()

也就是说,还有一些需要注意的问题

  • 在使用
    list[size++]
    之前,请确保
    size
    小于
    容量
    ,否则您将导致分配的内存溢出,从而产生错误
  • scanf(“%s”,缓冲区)应该是
    scanf(“%63s”,缓冲区)以防止任何可能的缓冲区溢出
  • 在使用返回的指针之前,请始终检查
    malloc()
    的返回值是否成功
  • sizeof(char)
    在C标准中定义为
    1
    。将其用作乘数是多余的
    • 而不是:

      list[size++] = reminder
      
      使用

      或者更好的是,在扫描时,记住写入的字符数,将其传递给add(),然后执行以下操作:

      strncpy(list[size++], reminder, len)
      

      您需要复制字符串;)我在想这个问题,但想知道这是否是解决这个问题最常用的方法?我想我只是在问是否每个人都这么做。。感谢OP在将内容分配给
      列表[size++]
      @chqrlie Yes,fair point之前还应测试
      大小
      。谢谢你的留言,我会在答案中加上<代码>strnpy
-->
strncpy
,不,strncpy无论如何都不是更安全的strcpy版本。:)不要使用
strncpy
,尤其是源字符串的长度作为额外参数<如果源字符串长于length参数,则code>strncpy
不会
'\0'
终止目标缓冲区。这个函数很容易出错。使用Sourav Gosh回答中的
strdup()
方法。
strncpy(list[size++], reminder, len)