【问题标题】:Structure with arrays and pointers带有数组和指针的结构
【发布时间】:2015-12-04 00:50:32
【问题描述】:

我必须编写一个程序来执行此操作,该程序将对有关何时 COP 3223 的 TA 可用的信息进行排序。该程序预计将读取所有 TA 办公时间班次的数据,然后对数据进行排序,然后以预先指定的格式打印出信息。假设最大班次数为100。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Given structure format that is needed to be used in the program. */
struct Shift
{
char name[100];
char day_of_week[100];
int start_hour;
int end_hour;
};

/* Functions that will be used in the program. */
int read_data(struct Shift shift_data[], int *num_shifts);
void sort_data(struct Shift shift_data[], int *num_shifts);
void print_data(struct Shift shift[], int num_shifts);

int main(void)
{
struct Shift shift_data[100];
struct Shift temp;

/*Declare and initialize variables, and statements to call each function. */
int num_shifts;

read_data(shift_data, &num_shifts);

sort_data(shift_data, &num_shifts);

print_data(shift_data, num_shifts);

return 0;
}

/*** Preconditions: array of structure "Shift" to store data
 Postconditions: number of shifts read in from data file
 Actions: Ask user for name of input file. Read the number of shifts, then read in the data for all
          of the shifts. Return the number of shifts. ***/
int read_data(struct Shift shift_data[], int *num_shifts)
{
/*Declare and initialize variables. */
char input_schedule[100];
int i;
char shift_name[100], shift_day[100];
/*Prompt user to enter the input file. */
printf("Enter the name of the file name.\n");
scanf("%s", &input_schedule[100]);
/*Declare file and read in the needed values. */
FILE *ifp;
ifp = fopen("input_schedule.txt", "r");
fscanf(ifp, "%d", &num_shifts);
/*For loop to read in each value from the file and store them in the shift_data array. */
for(i=0; i<(*num_shifts); i++)
{
     fscanf(ifp, "%s %s %d %d\n", &shift_data[i].name, &shift_data[i].day_of_week, &shift_data[i].start_hour, &shift_data[i].end_hour);
}
/*Close file.*/
fclose(ifp);

return num_shifts;
}
/*** Preconditions: array of structure "Shift" integer value indicating number of shifts
 Postconditions: none - this function does not return anything.
 Actions: Sort the shifts by the TA's first name. ***/
void sort_data(struct Shift shift_data[], int *num_shifts)
{
/*Declare and initialize variables. */
int i,j;
/*For loop to run through each array.*/
for(i=0; i<(*num_shifts); i++)
{
/*For loop to use the next element in the array to compare to the element before it.*/
    for(j=i+1; j<(*num_shifts); j++)
    {
/*If statements using strcmp to compare the two strings and sort the data in order.*/
        if(strcmp(shift_data[i].name,shift_data[i].name) < 0)
        {
            memcpy(temp.name, shift_data[i].name, strlen(shift_data[i].name) + 1);
            memcpy(shift_data[i].name, shift_data[j].name, strlen(shift_data[j].name) + 1);
            memcpy(shift_data[j].name, temp.name, strlen(temp.name) + 1);
        }
        if(strcmp(shift_data[i].day_of_week,shift_data[i].day_of_week) < 0)
        {
            temp.day_of_week = shift_data[i].day_of_week;
            shift_data[i].day_of_week = shift_data[j].day_of_week;
            shift_data[j].day_of_week = temp.day_of_week;
        }
        if(strcmp(shift_data[i].start_hour,shift_data[i].start_hour) < 0)
        {
            temp.start_hour = shift_data[i].start_hour;
            shift_data[i].start_hour = shift_data[j].start_hour;
            shift_data[j].start_hour = temp.start_hour;
        }
        if(strcmp(shift_data[i].end_hour,shift_data[i].end_hour) < 0)
        {
            temp.end_hour = shift_data[i].end_hour;
            shift_data[i].end_hour = shift_data[j].end_hour;
            shift_data[j].end_hour = temp.end_hour;
        }
    }

}
}

/*** Preconditions: array of structure "Shift" integer value indicating number of shifts
 Postconditions: none - this function does not return anything.
 Actions: Print the sorted data in the format described below. **/
void print_data(struct Shift shift_data[], int num_shifts)
{
/*Declare and initialize variables.*/
int i;

printf("\n\n\n");
/*For loop to print out the sorted data to the user.*/
for(i=0; i<num_shifts; i++)
{
    printf("%s\t\t", shift_data[i].name);
    printf("%s\t", shift_data[i].day_of_week);
    printf("%d to ", shift_data[i].start_hour);
    printf("%d\n", shift_data[i].end_hour);
/*If statements to change the shift times from military time to standard time.*/
    if(shift_data[i].start_hour > 12)
    {
        shift_data[i].start_hour = shift_data[i].start_hour - 12;
        printf("%2d:00 pm to  ", shift_data[i].start_hour);
    }
    else if(shift_data[i].start_hour < 12)
    {
        printf("%2d:00 am to  ", shift_data[i].start_hour);
    }
    else if(shift_data[i].start_hour == 12)
    {
        printf("%2d:00 pm to  ", shift_data[i].start_hour);
    }

    if(shift_data[i].end_hour > 12)
    {
        shift_data[i].end_hour = shift_data[i].end_hour - 12;
        printf("%2d:00 pm\n", shift_data[i].end_hour);
    }
    else if(shift_data[i].end_hour < 12)
    {
        printf("%2d:00 am\n", shift_data[i].end_hour);
    }
    else if(shift_data[i].end_hour == 12)
    {
        printf("%2d:00 pm\n", shift_data[i].end_hour);
    }
}
}

我遇到的问题在于 sort_data 函数。从“char *”类型分配给“char [100]”类型时,我不断收到错误消息,指出类型不兼容。这是我的临时变量,但我似乎无法弄清楚如何修复它。

【问题讨论】:

  • 最好准确说明哪一行代码给了你错误。我假设这个:shift_data[j].name = temp.name;。您不能更改数组本身的值。要更改数组的内容,您可能需要strncpy(shift_data[j].name, temp.name, sizeof(shift_data[j].name))
  • 我想你不知道你在这里做什么:if(strcmp(shift_data[i].start_hour,shift_data[i].start_hour) &lt; 0)。你应该这样做if(shift_data[i].start_hour &lt; shift_data[i].start_hour)
  • scanf("%s", &amp;input_schedule[100]); 是个错误。您刚刚告诉它在数组末尾 之后开始写入... 而应该是 scanf("%99s", input_schedule)
  • fscanf(ifp, "%d", &amp;num_shifts); 也是一个错误。想想num_shifts 是什么。
  • 你有很多行,你 strcmp 一个字符串本身 - 这将始终匹配

标签: c


【解决方案1】:

当你在 C 中使用 char 数组进行赋值时,它不会复制数组的内容。

代替使用:

temp.name = shift_data[i].name;

做:

strncpy(temp.name, shift_data[i].name, 99);
temp.name[99] = '\0';

对不起,我建议你使用memcpy(),但你必须检查字符串的长度才能知道要复制多少字节,这不是正确使用的函数。

使用strncpy 更好,因为复制在到达空字节或 可以存储的最大字符数。请注意,您的字符串长度为10099 将使 strncpy 在您的字符串中从索引 0 复制到 98。而temp.name[99] = '\0'; 行将用\0 填充字符串的最后一个位置。

在这个页面上:http://linux.die.net/man/3/strncpy,对strncpy有更好的描述和这个函数的简单代码。

【讨论】:

    【解决方案2】:

    您的代码的问题是无法复制数组(出于某种原因)。另一方面,结构可以简单地将您的数组转换为包含具有相同大小的数组的结构。

    它看起来像这样:

    typedef struct { char day_of_week[100]; } tmpType;
    
    *(tmpType*)temp.day_of_week = *(tmpType*)shift_data[i].day_of_week;
    

    这样可以避免调用外部库函数(对于某些编译器)。

    如果您想了解有关数组的更多信息,我建议您在 Google 中搜索“数组到指针衰减”。

    但我怀疑您的代码中的另一个问题是您的“temp”变量未在您使用它的函数“sort_data”的范围内定义。

    我猜你的意思是让它成为一个全局变量。如果是这种情况,您必须在 main 之外定义它,如下所示:

    struct Shift temp;
    
    int main(void)
    {
    /*your main code*/
    }
    

    您的固定函数应如下所示:

    void sort_data(struct Shift shift_data[], int *num_shifts)
    {
    
    typedef struct { char arr[100]; } tmpType;
    
    /*Declare and initialize variables. */
    int i,j;
    /*For loop to run through each array.*/
    for(i=0; i<(*num_shifts); i++)
    {
    /*For loop to use the next element in the array to compare to the element before it.*/
        for(j=i+1; j<(*num_shifts); j++)
        {
    /*If statements using strcmp to compare the two strings and sort the data in order.*/
            if(strcmp(shift_data[i].name,shift_data[i].name) < 0)
            {
                memcpy(temp.name, shift_data[i].name, strlen(shift_data[i].name) + 1);
                memcpy(shift_data[i].name, shift_data[j].name, strlen(shift_data[j].name) + 1);
                memcpy(shift_data[j].name, temp.name, strlen(temp.name) + 1);
            }
            if(strcmp(shift_data[i].day_of_week,shift_data[i].day_of_week) < 0)
            {
                *(tmpType*)temp.day_of_week = *(tmpType*)shift_data[i].day_of_week;
                *(tmpType*)shift_data[i].day_of_week = *(tmpType*)shift_data[j].day_of_week;
                *(tmpType*)shift_data[j].day_of_week = *(tmpType*)temp.day_of_week;
            }
            if(strcmp(shift_data[i].start_hour,shift_data[i].start_hour) < 0)
            {
                temp.start_hour = shift_data[i].start_hour;
                shift_data[i].start_hour = shift_data[j].start_hour;
                shift_data[j].start_hour = temp.start_hour;
            }
            if(strcmp(shift_data[i].end_hour,shift_data[i].end_hour) < 0)
            {
                temp.end_hour = shift_data[i].end_hour;
                shift_data[i].end_hour = shift_data[j].end_hour;
                shift_data[j].end_hour = temp.end_hour;
            }
        }
    
    }
    }
    

    如果您愿意,也可以使用类似的方法来复制您的“姓名”成员。

    【讨论】:

    • 这里的问题是这仍然不能正确地对列表进行排序(如果您修复了代码以实际正确地对列表进行排序,那么这种转换就没有必要了)
    猜你喜欢
    • 2013-02-16
    • 2016-06-23
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2016-06-30
    相关资源
    最近更新 更多