2012-07-16 71 views
2

我想知道为什么下面的代码行为如下。我第一次打印变量“account_name”它可以正常工作。第二次和第三次,它根本不起作用,而是打印乱码。我在C.C函数输入字符串

const char * get_account_name(){ 

    char loc_account_name[255]; 

    printf ("Please enter the ledger Account name: "); 
    scanf ("%[^\n]", &loc_account_name); 
    fflush(stdin); 
    printf ("\n"); 
    return (loc_account_name); 
} 

void main (void) 
{ 

    /* Declare variables. We use the predefined "MAX_ENTRIES" definition to define how large the arrays will be */ 

    float credits[MAX_ENTRIES], debits [MAX_ENTRIES], starting_balance, ending_balance; 
    int  debit_amount, credit_amount, x; 
    char * account_name; 

    printf ("Welcome to the Sears Ledger System\n\n"); 

    /* Prompt the user to enter the name of the account, we allow for up to 255 characters and account for names with spaces as well */ 
    account_name = get_account_name(); 
    printf("%s",account_name); 
    printf("%s",account_name); 
    printf("%s",account_name); 


} /* end main*/ 

*更新

初学者我已删除的get_account_name功能的scanf函数的符号。然后我发现它会不止一次地打印出正确的值,但是程序会在那之后永远挂起。不幸的是,我被迫使用的编译器没有调试器,所以我仍然对发生的事情感到困惑。

char * get_account_name(){ 

    char * loc_account_name; 
    printf ("Please enter the ledger Account name: "); 
    scanf ("%[^\n]", loc_account_name); 
    fflush(stdin); 
    printf ("\n"); 

    return loc_account_name; 

} 

* *更新2

char *get_account_name() { 

    char loc_account_name[255]; 
    char *r; 

    printf ("Please enter the ledger Account name: "); 
    scanf ("%[^\n]", &loc_account_name); 
    fflush(stdin); 
    printf("%s\n", loc_account_name); 

    *r = malloc(strlen(loc_account_name) + 1); 
    strcpy(r, loc_account_name); 
    return r; 
} 

void main (void) 
{ 

    char  * account_name; 

    /* Prompt the user to enter the name of the account, we allow for up to 255 characters and account for names with spaces as well */ 
    account_name = get_account_name(); 
    printf("%s\n", account_name); 
    printf("%s\n", account_name); 
    printf("%s\n", account_name); 
    free(account_name); 


} /* end main*/ 
+0

'scanf(“%[^ \ n]”,...)'这是否工作? – Ashe 2012-07-16 02:14:23

+0

是的,迄今为止我已经工作 – user1527739 2012-07-16 02:57:39

回答

4

您从get_account_name()返回一个局部变量loc_account_name的地址。该函数返回后,该内存不存在。 (嗯,它看起来像它仍然包含了很短的时间相同的数据,但你不使用它的第二次或第三次)

为了解决这个问题,您可以:

  • 分配空间(使用malloc()或类似的)作为get_account_name()函数中的字符串,并返回指向该空间的指针。调用者将负责释放内存。

    char *get_account_name() { 
        char loc_account_name[255]; 
        // get user input into loc_account_name 
        char *r = malloc(strlen(loc_account_name) + 1); 
        strcpy(r, loc_account_name); 
        return r; 
    } 
    
    account_name = get_account_name(); 
    // use account_name 
    free(account_name); 
    

    注意,您可以使用strdup()代替malloc()/strcpy()如果你的运行时库有其中的一个。

  • 具有呼叫者分配一些空间用于字符串的最大长度,以及缓冲液(和缓冲区的长度)通入get_account_name()函数为它在继续进行。

    void get_account_name(char *buffer, int buffer_size) { 
        // get user input into buffer 
        // but make sure the user can't type more than buffer_size characters! 
    } 
    
    char account_name[255]; 
    get_account_name(account_name, sizeof(account_name)); 
    // use account_name 
    

返回函数中的字符串在C中很笨拙和烦人。这就是为什么大多数现代语言(包括C++)具有更好的内置方式来处理字符串的原因。

+0

我已经删除了&符号,以便它不再返回本地变量的地址。我不确定是否需要修复它,因为尽管它现在确实不止一次地打印了正确的字符串,但它永远挂起。 (我没有调试功能)您能否使用您的一种方法发布更详细的响应,因为我不熟悉这两种方法。 – user1527739 2012-07-16 03:04:38

+0

您的更新代码现在将用户文本读入由未初始化的'loc_account_name'指针指向的内存中的某个随机位置。正如你所注意到的,这也是错误的。我将添加一些代码示例。 – 2012-07-16 03:08:29

+0

我已经尝试了上面的第一个解决方案,但结果与删除&符号非常相似。系统连续写出正确的文本3次,然后崩溃(我的简单挂起而不是崩溃,但不是太不相似)它似乎与“免费(”声明 – user1527739 2012-07-16 03:26:33

0

在单线程环境中,您可以简单地使用一个静态缓冲区,如:

const char *get_account_name(void) { 

    static char loc_account_name[255]; 
    int c; 

    printf ("Please enter the ledger Account name: "); 
    scanf ("%254[^\n]", loc_account_name); 
    while((c=getchar())!=EOF && c!='\n'); 
    printf("%s\n", loc_account_name); 

    return loc_account_name; 
} 

清除输入缓冲区,你应该永远使用一个符合标准的方式。