0

我正在努力学习使用结构。将文件加载并读取到 struct c 中,打印文件!

我正在尝试逐行阅读!并打印每行的姓名和姓氏!

......

int memmove(struct students*s, char line){

int count;  /* The current number of entries in the array */
int remove; /* The entry to remove (index into array, so zero based) */

/* Move the still valid entries one step "down" in the array */

printf("tabort?: ");
        scanf("%s", &line);
    memmove(s + remove, s + (remove + 1),
   sizeof(struct students) * (count - remove - 1));

count--;  /* Now contains one less entry */

}
4

2 回答 2

0

而不是执行 fscanfin print(您应该只打印,而不是从文件中读取任何内容)scanf在 load 中执行 -family 调用。这是一个几乎完整的示例,说明我将如何做到这一点:

#include <stdio.h>
#include <ctype.h>

#define MAX_NAME_LENGTH  100
#define MAX_STRUCTS      100

struct analg
{
    char f_name[MAX_NAME_LENGTH];
    char l_name[MAX_NAME_LENGTH];
};

/* Load from the named file, into the `analg` array provided, but no more than `max` entries */
/* Returns the number of entries loaded */
int load(char *filename, struct analg *h, int max)
{
    int count = 0;  /* The number of entries we have loaded */

    FILE *fp = fopen(filename, "r");

    char line[MAX_NAME_LENGTH * 2];  /* *2 for first and last name */

    if (fp == NULL)
        return;  /* File could not be opened */

    /* Read all lines, but only as long as we have available entries in the array */
    while (count < max && fgets(line, sizeof(line), fp) != NULL)
    {
        /* Extract the first and last names from the newly read line */
        sscanf(line, "%s %s", h[count].f_name, h[count].l_name);
        count++;  /* Increase counter so we have the current size */
    }

    /* All done loading */
    fclose(fp);

    return count;  /* Return the number of entries we loaded */
}

/* Print from the structure array, there are `count` entries in the array */
void print(struct analg *h, int count)
{
    for (int i = 0; i < count; i++)
    {
        /* Print the number and the names */
        /* +1 to the index, because it starts from zero and we want to print it nicely to the user and start from 1 */
        printf("Number %2d: %s %s\n", i + 1, h[i].f_name, h[i].l_name);
    }
}

int main(void)
{
    struct analg h[MAX_STRUCTS];

    int choice;
    int count = 0;  /* Initialize to zero, in case user chooses `print` first */

    do
    {
        printf("choose L or P: ");

        /* Read input from user, as a character, while skipping leading and trailing whitespace */
        scanf(" %c ", &choice);

        switch (tolower(choice))
        {
        case 'l':
            count = load("text.txt", h, MAX_STRUCTS);
            if (count == 0)
                printf("No structures loaded\n");
            break;

        case 'p':
            print(h, count);
            break;

        case 'q':
            /* Do nothing, just catch it for error reporting (below) will work */
            break;

        default:
            printf("\nPlease only use 'p' or 'l', or 'q' for quit\n");
            break;
        }
    } while (tolower(choice) != 'q');

    return 0;
}

OP 还想知道如何在读取条目后删除条目。首先要记住的是,这些行是按顺序从文件中加载的,因此要在数组中找到特定的行,您只需将文件中的行号减去一个(因为数组索引是从零开始的)。

对于实际删除,有几个解决方案:

  1. 在结构中保留一个布尔标志,以判断它是否有效。删除条目时,只需将标志设置为“false”,打印或保存或其他处理时忽略标志为“false”的所有条目。

  2. 将要删除的条目上方的条目下移一级。这将覆盖您要删除的条目,因此它不再存在。它比第一个解决方案工作更多,但不会在数组中留下未使用的条目。

    它是通过使用完成的memmove

    int count;  /* The current number of entries in the array */
    int remove; /* The entry to remove (index into array, so zero based) */
    
    /* Move the still valid entries one step "down" in the array */
    memmove(h + remove, h + (remove + 1),
           sizeof(struct analg) * (count - remove - 1));
    
    count--;  /* Now contains one less entry */
    

    如果您想知道h + remove表达式,它称为指针算术h[remove],并使用表达式与 相同的事实*(h + remove),这意味着h + remove与 相同&h[remove]

  3. 不要使用数组,而是使用链表,在其中添加新行。这是最有效的解决方案,您也无法轻松删除特定行。然而,这种方法可以很容易地删除(和添加)列表中任何位置的节点。

如果您想要结构中的其他字段,例如年龄,则只需添加该字段。您当然需要修改文本文件的解析,但如果新字段放在文本文件的行尾,那么只需在sscanf调用中添加另一种格式。并且在查找将特定字段设置为特定值的条目时,只需遍历数组(或列表)并将该字段与所需值进行比较。

于 2013-02-27T20:13:31.173 回答
0

对您的程序进行了一些更改以使其正常工作

#include<stdio.h>

struct analg {
char f_name[100];
char l_name[100];
};
struct analg h;
FILE *fp;




void load() 
{
fp = fopen("text.txt", "r");

  if(fp == NULL)
  {
   printf("fail");
   return; 
  }

fgets(h.f_name, 100, fp); 
fgets(h.l_name, 100, fp); 


printf("file loaded!\n");
fclose(fp);
return;
}


void print()
{
    fscanf(fp,"%s %s\n",h.f_name,h.l_name);
    printf ("%s\n",h.f_name);
    printf ("%s\n",h.l_name);
return;
}


int main ()
{
char choice;
do{ 
printf("choose L or P: ");
scanf("%c", &choice);
switch(choice)
 {
  case 'l': 
    load();
    printf("\n[l]oad - [p]rint\n");
    break;
  case 'p': 
    print();
    printf("\n[l]oad - [p]rint\n");
    break;    

  default:        
    break;
 }
 }  
 while(choice!='q');

 return 0;
}
于 2013-02-27T20:24:11.003 回答