简体   繁体   English

将 char 指针的返回值设置为 char 数组

[英]Setting return value of char pointer to a char array

Trying to learn C. To that end, I'm coding a program that creates a TroubleTicket report.尝试学习 C。为此,我正在编写一个程序来创建 TroubleTicket 报告。 The user is prompted to enter, priority, name and problem.提示用户输入优先级、名称和问题。 I'm using a struct to store the data and create a struck array.我正在使用一个结构来存储数据并创建一个被击中的数组。 Using the array approach for now as I'm developing the code.在我开发代码时暂时使用数组方法。 Eventually, I'd to use a linked list.最终,我会使用链表。

Anyhow, the get_input() function reads in the user input and returns a char pointer.总之,get_input() function 读取用户输入并返回一个字符指针。 Included the get_input() and create_ticket() functions.包括 get_input() 和 create_ticket() 函数。

#define NUM_TICKETS 10

char* get_input(int maxlen)
{
    static char s[110];
    char ch;
    int i = 0;
    int chars_remain = 1;

    while (chars_remain)
    {
        ch = getchar();
        if ((ch == '\n') || (ch == EOF))
        {
            chars_remain = 0;
        }
        else if (i < maxlen - 1)
        {
            s[i] = ch;
            i++;
        }
    }
    s[i] = '\0';
    return s;
    
void create_ticket()
{
    struct ticket
    {
        int priority;
        int number;
        char * name;
        char * problem ;
        char * assigned_to;
        char * status ;
    };
    struct ticket tkt_array[NUM_TICKETS];
    struct ticket new_ticket;
    
    printf("Enter your name: ");
    new_ticket.name = get_input(20);
    printf("new_ticket.name: %s \n", new_ticket.name);
        
    printf("Enter problem description: ");
    new_ticket.problem = get_input(100);
    printf("new_ticket.problem: %s \n", new_ticket.problem);
    
    printf("Assigned to: ");
    new_ticket.assigned_to = get_input(20);
    printf("new_ticket.assigned_to %s\n ", new_ticket.assigned_to);
    
    printf("Enter ticket status: ");
    new_ticket.status = get_input(10);
    printf("new_ticket.status: %s \n", new_ticket.status);
    
}

I noticed that initial input was read and displayed correctly but subsequent inputs overwrote prior input.我注意到初始输入已被正确读取和显示,但后续输入覆盖了先前的输入。

For example, after name was entered, the entered value is displayed例如,输入名称后,显示输入的值

printf("Enter your name: ");
new_ticket.name = get_input(20);
printf("new_ticket.name: %s \n", new_ticket.name);

But after problem description is entered, new_ticket.name was changed to display the problem description text.但是输入问题描述后,new_ticket.name 改为显示问题描述文本。 Took me a while to figure out that the problem is the return s in get_char().我花了一段时间才弄清楚问题出在 get_char() 中的 return s。 It returns a pointer.它返回一个指针。 The address is the same but the value changes and struct ticket pointers point to the same address of return s from get_char().地址相同,但值发生变化,struct ticket 指针指向从 get_char() 返回的相同地址。 How can I save the return value in a variable and not get it reset on subsequent call to get_input?如何将返回值保存在变量中而不在随后调用 get_input 时重置它? s is a char *, how can I save the return value of a pointer in a variable? s是一个char *,如何将指针的返回值保存到变量中?

printf("Enter problem description: ");
new_ticket.problem = get_input(100);
printf("new_ticket.problem: %s \n", new_ticket.problem);
printf("new_ticket.name: %s \n", new_ticket.name);

How can I save the return value in a variable and not get it reset on subsequent call to get_input?如何将返回值保存在变量中而不在随后调用 get_input 时重置它? s is a char *, how can I save the return value of a pointer in a variable? s是一个char *,如何将指针的返回值保存到变量中? I hope I clearly stated the issue.我希望我清楚地说明了这个问题。

This answer addresses only the problem stated in the question, not other errors or problems in your code.此答案仅解决问题中所述的问题,而不解决代码中的其他错误或问题。

Your function get_input uses a single array static char s[110];您的 function get_input使用单个数组static char s[110]; to store the input and always returns the address of this array.存储输入并始终返回该数组的地址。

Assignments like new_ticket.name = get_input(20);new_ticket.name = get_input(20);这样的赋值will store the same address in all pointer variables, so all will actually point to the same variable s which will contain the last input.将在所有指针变量中存储相同的地址,因此所有指针变量实际上都将指向包含最后一个输入的相同变量s

One option to solve this would be to replace the pointers in your structure with arrays and either pass this to get_input or copy the value using strcpy .解决此问题的一种选择是将结构中的指针替换为 arrays 并将其传递给get_input或使用strcpy复制值。

Or you could use the (non-standard) function strdup to get a dynamically allocated duplicate of the input string.或者您可以使用(非标准)function strdup来获取输入字符串的动态分配副本。 If this function is not available, you could implement it using malloc and strcpy .如果这个 function 不可用,您可以使用mallocstrcpy来实现它。

Example:例子:

    new_ticket.name = strdup(get_input(20));

Note: When using strdup , you should free the memory when it's no longer needed.注意:使用strdup时,您应该在不再需要时free memory。

or using a replacement for strdup :或使用strdup的替代品:

    const char *s1;
    char *s2;
/* ... */

    s1 = get_input(20);
    s2 = malloc(strlen(s1) + 1);
    if(s2 == NULL)
    {
        /* handle error */
    }
    else
    {
        strcpy(s2, s1);
    }
    new_ticket.name = s2;

(You could implement your own function that wraps malloc and strcpy .) (您可以实现自己的 function 包装mallocstrcpy 。)

or with arrays instead of pointers as structure fields或者使用 arrays 而不是指针作为结构字段

    struct ticket
    {
        int priority;
        int number;
        char name[20];
        char problem[100];
        char assigned_to[20];
        char status[10];
    };

/* ... */
    strcpy(new_ticket.name, get_input(sizeof(new_ticket.name));

The static keyword creates a value that exists once, so multiple invocations of the function point to the same data. static关键字创建一个存在一次的值,因此 function 的多次调用指向相同的数据。

If you want to dynamically create data with a lifetime that you control, you may allocate your own memory.如果您想动态创建具有您控制的生命周期的数据,您可以分配您自己的 memory。

malloc(size) will allocate a block of memory with the size provided. malloc(size)将分配一个大小为 memory 的块。 This memory will exist and be valid until you call free on that memory.此 memory 将存在并有效,直到您free拨打该 memory。

You should be careful though, calling free twice, or forgetting to call it at all, are common sources of bugs within c code.但是你应该小心,调用free两次,或者根本忘记调用它,是 c 代码中错误的常见来源。

The other option in this is to have the caller of the function provide the memory. You could change your struct ticket to have char name[MAX_NAME_LEN] , and update the function get input to get_input(int max_len, char * buffer) .另一个选项是让 function 的调用者提供 memory。您可以将struct ticket更改为具有char name[MAX_NAME_LEN] ,并将 function get 输入更新为get_input(int max_len, char * buffer) This also solves the problem, while avoiding potentially erroneous malloc and free s.这也解决了问题,同时避免了潜在的错误mallocfree s。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM