尝试在结构字符串中编辑字符串时出错

Posted

技术标签:

【中文标题】尝试在结构字符串中编辑字符串时出错【英文标题】:Error trying to edit character string inside struct string 【发布时间】:2021-06-27 00:36:58 【问题描述】:

我的程序包含下一个结构:

typedef struct user 
    char username[LENGTH_USERNAME];
 User

我在 struct user 的主函数中有一个数组

User user_database[NUMBER_USERS];

问题是当我将此数据库传递给一个函数来编辑数组中所有结构用户的用户名字段时,如下所示:

void initialize_empty_user_database(User database[])

    int i;
    for(i = 0; i < NUMBER_USERS; ++i)
        database[i].username[0] = '\0';

尝试编译时,出现下一个错误:

 error: incompatible types when assigning to type ‘User’ aka ‘struct user’ from type ‘char *’

完整代码如下:

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

#define LENGTH_USERNAME 21
#define LENGTH_ACTIVITY_NAME    21
#define LENGTH_TASK_DESCR   51
#define NUMBER_USERS    50
#define NUMBER_ACTIVITIES   10
#define NUMBER_TASKS    10000

typedef struct user 
    char username[LENGTH_USERNAME];
    /* username cannot contain blank characters */
 User;


typedef struct activity 
    char name[LENGTH_ACTIVITY_NAME];      
    /* name cannot contain lowercase letters */
 Activity;

typedef struct task 
    int id;             
    char des[LENGTH_TASK_DESCR];                    /* description */
    User username[LENGTH_USERNAME];
    Activity activity[LENGTH_ACTIVITY_NAME];
    int etc;                                        /* Estimated Time of Completion */
    int start_time;     
 Task;

void initialize_empty_user_database(User database[])

    int i;
    for(i = 0; i < NUMBER_USERS; ++i)
        database[i].username[0] = '\0';


void initialize_empty_activity_database(Activity database[])

    int i;
    for(i = 0; i < NUMBER_ACTIVITIES; ++i)
        database[i].name[0] = '\0';


void initialize_empty_task_database(Task database[])

    int i;
    for(i = 0; i < NUMBER_TASKS; ++i) 
        database[i].id = -1;                        /* id == -1 -> task not initialized */
    


void read_task_descr(char target[])

    int i;
    char c;
    c = getchar();
    for(i = 0; i < (LENGTH_TASK_DESCR - 1) || c == '\n'; ++i)
        target[i] = c;
        c = getchar();
    
    target[i] = '\0';


int available_tasks(Task database[])

    int i;
    for(i = 0; i < NUMBER_TASKS; ++i) 
        if(database[i].id == -1)
            return NUMBER_TASKS - i;
    
    return 0;


int duplicate_descr(Task database[], char descr[]) 

    int i;
    for(i = 0; i < NUMBER_TASKS; ++i) 
        if (strcmp(database[i].des, descr) == 0)
            return 1;
    
    return 0;


int t_exceptions(Task task_database[], char task_descr[])

    if (available_tasks(task_database) == 0) 
        printf("too many tasks");
        return 1;
    
    else if (duplicate_descr(task_database, task_descr) == 1) 
        printf("duplicate description"); 
        return 2;
    
    return 0;


void new_task(Task database[], int etc, char descr[]) 

    static int i = 0;
    database[i].id = i + 1;                         /* id */
    strcpy(database[i].des, descr);                 /* descr */
    database[i].username[0] = '\0';                 /* username (not attributed) */
    strcpy(database[i].activity.name, "TO DO");     /* activity */
    database[i].etc = etc;                          /* estimated time for completion */
    database[i].start_time = 0;                     /* start time (not started) */
    ++i;



int main()

    /* Database declarations */
    User user_database[NUMBER_USERS];
    Activity activity_database[NUMBER_ACTIVITIES] = "TO DO", "IN PROGRESS", "DONE";
    Task task_database[NUMBER_TASKS];
    
    /* Variable and array definition */
    int time;
    int etc;                                        /* estimated time of completion */
    char task_descr[LENGTH_TASK_DESCR];
    char activity_name[LENGTH_ACTIVITY_NAME];
    char username[LENGTH_USERNAME];
    
    /* Auxiliary variables */
    char command;

    /* Database initilizations */
    initialize_empty_user_database(user_database);
    initialize_empty_activity_database(activity_database);
    initialize_empty_task_database(task_database);

    while(1) 
        command = getchar();
        switch(command) 
            case 'q':
                return 0;
            case 't':
                scanf("%d", &etc);
                getchar();  /* Consume space separating arguments */
                read_task_descr(task_descr);
                if(t_exceptions(task_database, task_descr) == 0)
                    new_task(task_database, etc, task_descr);       
                break;
            default:
                printf("Exception: Unknown command\n");
        
        getchar(); /* Consume the newline character */
    
    return -1;

有人可以向我解释我做错了什么吗?

谢谢!

原代码中的错误是:

main.c: In function ‘new_task’:
main.c:103:31: error: incompatible types when assigning to type ‘User’ aka ‘struct user’ from type ‘int’
  103 |     database[i].username[0] = '\0';                 /* username (not attributed) */
      |                               ^~~~
main.c:104:32: error: ‘(Activity *)&(database + (sizetype)((long unsigned int)i * 948))->activity’ is a pointer; did you mean to use ‘->’?
  104 |     strcpy(database[i].activity.name, "TO DO");     /* activity */
      |                                ^
      |                                ->

【问题讨论】:

你确定这是错误所在吗?它们似乎不匹配。 请提供完整的代码minimal reproducible example。显示的代码不完整,错误消息似乎与显示的代码不匹配。 那还不是完整的代码。显示您正在编译的 exact 代码,并在错误消息中包含 exact 行号。它应该是完整的,任何人都可以获取代码,编译它并查看您的错误。 错误不在您已识别的行上。如果您在错误消息中提供行号,这将非常有帮助。错误是这一行:database[i].username[0] = '\0';database 的类型是 Task,而该结构中 username 的类型是 User 数组。您可能打算将 username 类型改为 char username[LENGTH_UERNAME] 谢谢,就是这个,我需要 .username->username 【参考方案1】:

错误在这一行:

database[i].username[0] = '\0'; 

这是因为username 被声明为User 数组:

typedef struct task 
    int id;             
    char des[LENGTH_TASK_DESCR];                    /* description */
    User username[LENGTH_USERNAME];
    Activity activity[LENGTH_ACTIVITY_NAME];
    int etc;                                        /* Estimated Time of Completion */
    int start_time;     
 Task;

这看起来像是字段声明中的错误,应该是:

char username[LENGTH_USERNAME];

【讨论】:

【参考方案2】:

表达式user_database[i].username[0] 的类型为char,因此您需要为其分配char 而不是字符串。

user_database[i].username[0] = '\0';

注意单引号不是双引号'\0'

【讨论】:

仍然得到相同的错误:main.c:103:31:错误:从类型“int”103 分配给类型“用户”aka“结构用户” 时类型不兼容 |数据库[i].username[0] = '\0'; 我复制了您提供的所有代码并添加了一个 main,其中仅包含一行以调用您的函数:initialize_empty_user_database(user_database); 我没有收到任何编译错误或警告,它执行良好。您应该复制确切的代码,以便我们可以复制它。

以上是关于尝试在结构字符串中编辑字符串时出错的主要内容,如果未能解决你的问题,请参考以下文章

尝试在 C++ 中使用 boost 正则表达式匹配从字符串转换为 int 时出错

尝试从要显示在 ListView 中的字符串列表中读取项目时出错

从功能区运行宏时出错

尝试反转除特殊字符外的字符串时出错

在 Python 中从 JSON 字符串中提取数据时出错(使用 Redshift)

尝试将字符串转换为双精度时出错