所以我在这里有很多代码:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#pragma warning(disable: 4996)
#define max 100
typedef enum { diploma, bachelor, master, doctor } education;
struct person { // a node to hold personal details
char name[30];
char email[30];
int phone;
education degree;
};
struct person directory[max]; // an array of structures, 100 entries
int tail = 0; // global variable
void flush(); // forward declaration of functions
void branching(char c);
int insertion();
int print_person(int i);
int print_all();
int search_person();
int delete_person();
int main() { // print a menu for selection
char ch = 'i';
ungetc('\n', stdin); // inject the newline character into input buffer
do {
printf("Enter your selection\n");
printf("\ti: insert a new entry\n");
printf("\td: delete an entry\n");
printf("\ts: search an entry\n");
printf("\tp: print all entries\n");
printf("\tq: quit \n");
flush(); // flush the input buffer. To be discussed later
ch = tolower(getchar());
branching(ch);
} while (ch != 113);
return 0;
}
void flush() { // flush the input buffer. To be discussed later
int c;
do {
c = getchar();
} while (c != '\n' && c != EOF);
}
void branching(char c) { // branch to different tasks
switch (c) {
case 'i':
insertion();
break;
case 's':
search_person();
break;
case 'd':
delete_person();
break;
case 'p':
print_all();
break;
case 'q':
break;
default:
printf("Invalid input\n");
}
}
int insertion() { // insert a new entry at the end
if (tail == max) {
printf("There are no more places to insert.\n");
return -1;
}
else {
printf("Enter name, phone, email, degree:\n");
scanf("%s", directory[tail].name);
// &directory[tail].name is an array. No "&" is needed
scanf("%d", &directory[tail].phone, sizeof(directory[tail].phone));
scanf("%s", directory[tail].email);
scanf("%s", &directory[tail].degree);
tail++;
printf("The number of entries = %d\n", tail);
return 0;
}
}
int print_person(int i) {
// print all information one person in the directory
printf("\n\nname = %s\n", directory[i].name);
printf("email = %s\n", directory[i].email);
printf("phone = %d\n", directory[i].phone);
printf("degree = %s\n", &directory[i].degree);
return 0;
}
int print_all() {
// print all information each person in the contactbook
int i;
if (tail == 0) {
printf("No entries found.");
}
else {
for (i = 0; i < tail; i++) {
print_person(i);
}
}
return 0;
}
int search_person() { // print phone and email via name
char sname[30]; int i;
char *p = sname;
printf("Please enter the name to be searched for:\n");
scanf("%s", sname); //sname is an array, no & needed
for (i = 0; i<tail; i++)
if (strcmp(p, directory[i].name) == 0) {
print_person(i);
return i;
}
printf("The name does not exist.\n");
return -1;
}
int delete_person() {
int i, k;
k = search_person();
if (k == -1) {
printf("The name does not exist.\n"); return -1;
}
else {
for (i = k; i<tail; i++) {
strcpy(directory[i].name, directory[i + 1].name);
directory[i].phone = directory[i + 1].phone;
strcpy(directory[i].email, directory[i + 1].email);
printf("The index deleted is: %d\n", k);
}
tail--;
return k;
}
}
我已经设法回答了我需要的几个问题,但我似乎无法找到其中两个。
问题:
进一步修改insert()函数,以便将新人插入到人员姓名的排序位置的目录(数组)中(保持数组中的数据按名称按升序排序)。
修改search_person()函数。使用while循环替换for循环,在循环中,使用指针操作而不是数组操作来迭代数组元素。
对于问题2,这是我必须修改的代码:
int insertion() { // insert a new entry at the end
if (tail == max) {
printf("There are no more places to insert.\n");
return -1;
}
else {
printf("Enter name, phone, email, degree:\n");
scanf("%s", directory[tail].name);
// &directory[tail].name is an array. No "&" is needed
scanf("%d", &directory[tail].phone, sizeof(directory[tail].phone));
scanf("%s", directory[tail].email);
scanf("%s", &directory[tail].degree);
tail++;
printf("The number of entries = %d\n", tail);
return 0;
}
}
我完全不知道我应该在这做什么。我坐在这里查看代码,不知道如何处理它。甚至问题本身也让我感到困惑。
对于问题3,要修改的代码是:
int search_person() { // print phone and email via name
char sname[30]; int i;
char *p = sname;
printf("Please enter the name to be searched for:\n");
scanf("%s", sname); //sname is an array, no & needed
for (i = 0; i<tail; i++)
if (strcmp(p, directory[i].name) == 0) {
print_person(i);
return i;
}
printf("The name does not exist.\n");
return -1;
}
所以我认为我设法做了指针操作部分(虽然我不是100%确定我做得正确)。我感到困惑的是如何使用while循环来替换for循环。我尝试了几个while循环,但它总是说我搜索的“名称”不存在。
如果有人能向我解释我应该如何处理这些问题,并向我解释我应该做些什么,这将是非常好的。谢谢!
答案 0 :(得分:0)
第二个(for while循环)一个更容易。 我将向您展示将for循环转换为while循环的通用方法,并让您执行代码,因为您正在尝试学习如何执行此操作。这是循环的一个例子:
int x;
for(x = 0; x < 10; x++)
{
//do stuff here
}
现在让我们做一个做同样事情的while循环:
int x;
x = 0;
while(x < 10)
{
//do stuff here
x++;
}
for循环有三个部分,初始化,条件和增量。
for( initialization , condition , incrementor )
初始化仅在首次到达for循环时发生一次。
条件在第一次初始化之后完成,然后每次再次到达循环的顶部,以查看循环是否应该再次执行,或者应该被跳过。
每次循环执行一次后,增量器就会发生。
while循环只有一个条件。可以在while循环之前添加初始化,并且可以将增量函数添加为while循环中的最后一个。
对于您的第一个问题,按名称按字母顺序插入,您实际上必须移动数组中的其他内容。假设我们在数组中有四件事:
a e i o
现在说我们要添加g。我们需要先检查它应该去哪里。因此,我们逐个查看元素,如果我们要查看的元素应该在g之后,那么我们应该在我们正在查看的元素之前放入g。在这种情况下,我们会查看a
,e
,然后当我们查看i
时,我们就会知道g应该首先出现。所以我们知道我们希望g进入i
所在的位置。要使该位置为空,我们必须将数组中的其他所有内容移动到右侧,或者朝向数组的尾部移动。我们必须从头开始做这件事。我们将o
移动到更高的位置,并使其成为新的尾部。然后我们也将i
翻过来。这意味着我们有一个带有间隙的数组(我将使用下划线表示空白点):
a e _ i o
现在我们可以在我们制作的空位中放出新元素。
a e g i o
然后去吧!现在只需要使用该算法并对其进行编码!如果您遇到麻烦,我会很乐意与您详细了解详情。
答案 1 :(得分:0)
对于问题3,你可以使用指针算法。
int search_person() { // print phone and email via name
char sname[30]; int i;
char *p = sname;
printf("Please enter the name to be searched for:\n");
scanf("%s", sname); //sname is an array, no & needed
i = 0;
while(i<tale){
if (strcmp(p, ((directory + i )->name)) == 0) {
print_person(i);
return i;}
i++;
}
printf("The name does not exist.\n");
return -1;
}
答案 2 :(得分:0)
您可以使用以下方法在插入后对directory
数组进行排序。
void dir_copy(struct person* src, struct person* dest)
{
// since you are using arrays inside person structs
// if dynamic memory is used, copy each string separately
memcpy(src,dest,sizeof(struct person));
return;
}
void dir_sort(struct person* dir, int dir_size)
{
struct person temp;
int i,j;
for (i = 0; i < dir_size; i++) {
for (j = 0; j < dir_size - 1; j++) {
if (strcmp(dir[j].name, dir[j + 1].name) > 0) {
dir_copy(&temp,&dir[j]);
dir_copy(&dir[j],&dir[j + 1]);
dir_copy(&dir[j + 1],&temp);
}
}
}
}
int insertion() { // insert a new entry at the end
if (tail == max) {
printf("There are no more places to insert.\n");
return -1;
}
else {
printf("Enter name, phone, email, degree:\n");
scanf("%s", directory[tail].name);
// &directory[tail].name is an array. No "&" is needed
scanf("%d", &directory[tail].phone);
scanf("%s", directory[tail].email);
scanf("%s", &directory[tail].degree);
tail++;
printf("The number of entries = %d\n", tail);
dir_sort(&directory,tail);
return 0;
}
}
并使用
scanf("%d", &directory[tail].phone, sizeof(directory[tail].phone));
将抛出编译器警告
warning: too many arguments for format [-Wformat-extra-args]
scanf("%d", &directory[tail].phone, sizeof(directory[tail].phone));
^
因为它们没有形成为scanf
提供的字符串以匹配第三个参数,并且无论如何它不是变量。我觉得没有必要。
如果要打印枚举,请使用getter函数来获取字符串而不是模糊的整数变量。
const char* getDegreeName(enum education degree)
{
switch (degree)
{
case diploma: return "diploma";
case bachelor: return "bachelor";
/* etc... */
}
}
同样在获取度数值时使用setDegree
来比较用户输入字符串并设置枚举,而不是将字符串读取为枚举值,这是不明智的。
如果您想使用while
循环代替for
查看其他答案或谷歌搜索,您将获得大量材料,
最后,在C
中,数组变量只是一个const指针,因此您可以随时使用指针算法而不是使用数组表示。
这意味着,
directory[i]
与*(directory*i)