[英]Adding both string and single char values to same multi-dimensional list
正如標題所說。 我想做一個多維列表,其中每行第一列是描述,其余列是描述約會的月,日和小時。 所以基本上整個列表是一個日歷,其中每一行是一個約會。 我遇到嚴重問題的地方是處理第一列與其他列不同的事實。 我正在考慮制作鏈接列表,但后來我必須按時間和日期對行進行排序,並且比較鏈接列表上的那些行為的想法很難。
我認為這比現在感覺更難。 我認為我搞亂了數組的內存分配,因為我對C很新。
char** add_appointment(char **calendar,int a){
char **pointer;
if(a != 0){
calendar = realloc(calendar, (a+1)*sizeof(char **));
calendar[0] = malloc(20 * sizeof(char));
calendar[1] = malloc(1 * sizeof(char));
calendar[2] = malloc(1 * sizeof(char));
calendar[3] = malloc(1 * sizeof(char));
}
pointer = calendar;
char* description;
description = malloc(20*sizeof(char));
char month;
char day;
char hour;
int i;
printf("Add description, month, day and hour of the appointment\n");
fgets(description, 19, stdin);
description = realloc(description, strlen(description)+1);
description[strlen(description)+1] = '\0';
scanf("%c", &month);
scanf("%c", &day);
scanf("%c", &hour);
calendar[a][0] = *description;
calendar[a][1] = month;
calendar[a][2] = day;
calendar[a][3] = hour;
return pointer;
}
因此描述最大大小為20.我知道我應該添加'\\ 0',我拼命想做。 “a”來自主要功能,並告知日歷中當前的約會數量。 if循環在那里,因為第一次約會的內存分配是在main函數上進行的。 在命令行上寫入描述后,程序已經失敗,並且在此之后的幾個月內拒絕詢問。
所以有一些事情。 首先,由於c中的字符串存儲為字符數組,因此您需要一個char ***日歷,因為每個約會號碼需要一行,然后是4行char *用於約會。 其次,不是重新分配兩次,而是嘗試將輸入讀入緩沖區,掃描緩沖區,然后根據您需要的大小進行分配。 如果不真正了解您的項目規范,此代碼應該讓您了解如何格式化事物。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define maxApt 3
void addApt(char *** cal, int aptNum){
char month,day, hour,inBuf[20]="";
printf("give input\n");
if(fscanf(stdin, "%s %c %c %c", inBuf,&month, &day, &hour)!=4){
fprintf(stderr,"poorly formatted input\n");
return;
}
cal[aptNum][0]=(char*)malloc(strlen(inBuf));
strncpy(cal[aptNum][0], inBuf,20);
for(int i =1;i<4;i++){
cal[aptNum][i]=(char*)malloc(1);
}
cal[aptNum][1][0]=month;
cal[aptNum][2][0]=day;
cal[aptNum][3][0]=hour;
}
int main(){
char ***calendar=(char***)malloc(maxApt*sizeof(char**));
for(int i =0;i<maxApt;i++){
calendar[i]=(char**)malloc(4*sizeof(char*));
addApt(calendar, i);
}
for(int j=0;j<maxApt;j++){
for(int i =0;i<4;i++){
printf("%s ", calendar[j][i]);
}
printf("\n");
}
}
請注意,如果您希望人們描述能夠擁有空格,則需要以更復雜的方式進行解析。
而不是多維數組,我認為這將更適合struct
:它更清晰,更可擴展。 如果您想增長數據,那么保持容量呈指數級增長會產生更好的限制行為。 同樣,將界面與邏輯背后分離是一個好主意。
#include <stdlib.h> /* realloc, rand, EXIT_* */
#include <string.h> /* strncpy */
#include <stdio.h> /* printf, perror */
#include <assert.h> /* assert */
struct Appointment {
char desc[1024];
unsigned year, month, day, hour, minute;
};
struct Appointments {
struct Appointment *a;
size_t capacity, next_capacity, number;
};
/** Ensures that {as} has at least {min} entries.
@return Success. */
static int reserve(struct Appointments *const as, const size_t min) {
struct Appointment *a;
size_t c0, c1;
assert(as);
/* Already have enough. */
if(min <= as->capacity) return 1;
/* Calculate increase by Fibbinocci. */
if(!as->a) c0 = 8, c1 = 13;
else c0 = as->capacity, c1 = as->next_capacity;
while(c0 < min) c0 ^= c1, c1 ^= c0, c0 ^= c1, c1 += c0;
assert(c0 < c1);
/* Grow the capacity. */
if(!(a = realloc(as->a, sizeof *a * c0))) return 0;
as->a = a;
as->capacity = c0;
as->next_capacity = c1;
return 1;
}
/** Add to {as} an appointment with appointment values.
@return Success. */
static struct Appointment *appointment(struct Appointments *const as,
const char *desc, unsigned year, unsigned month, unsigned day,
unsigned hour, unsigned minute) {
struct Appointment *a;
assert(as && desc && month && month <= 12 && day && day < 31
&& hour < 24 && minute < 60);
/* Add a new entry. */
if(!reserve(as, as->number + 1)) return 0;
a = as->a + as->number++;
/* Copy (part of?) the data. */
strncpy(a->desc, desc, sizeof a->desc - 1);
a->desc[sizeof a->desc - 1] = '\0';
a->year = year;
a->month = month;
a->day = day;
a->hour = hour;
a->minute = minute;
return a;
}
/** Adds a random appointment to {as}.
@return Success. */
static struct Appointment *add_appointment(struct Appointments *const as) {
char desc[64];
/* Shhh, it's a Poisson distibuition. */
const size_t desc_len = 31 + rand() / (RAND_MAX / 32 + 1);
size_t i;
for(i = 0; i < desc_len; i++) desc[i] = (i ? 'a' : 'A')
+ rand() / (RAND_MAX / 26 + 1);
desc[i] = '\0';
/* http://c-faq.com/lib/randrange.html */
return appointment(as, desc, 2000 + rand() / (RAND_MAX / 100 + 1),
1 + rand() / (RAND_MAX / 12 + 1), 1 + rand() / (RAND_MAX / 28 + 1),
rand() / (RAND_MAX / 24 + 1), rand() / (RAND_MAX / 60 + 1));
}
int main(void) {
struct Appointments as = { 0, 0, 0, 0 };
size_t i = 99, j;
while(--i) if(!add_appointment(&as)) break;
for(j = 0; j < as.number; j++) {
struct Appointment *a = as.a + j;
printf("%04u-%02u-%02uT%02u:%02u %s\n", a->year, a->month, a->day,
a->hour, a->minute, a->desc);
}
free(as.a), as.a = 0;
return i ? perror("Appointments"), EXIT_FAILURE : EXIT_SUCCESS;
}
存儲日期的最佳方式是一個完全不同的問題。 例如, 存儲日期的最佳數據類型是什么 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.