【问题标题】:I want to search and display the information of a “contact” but it doesn’t work我想搜索并显示“联系人”的信息,但它不起作用
【发布时间】:2019-01-26 16:16:42
【问题描述】:

所以我有一个文件(即通讯簿),其中包含以这种方式格式化的人员信息

————————-联系方式—————————-

名字:托尼

姓:斯塔克

地址:马里布

电话号码:10203044032

电子邮件:tony.stark@jarvis.com

公司/工作地点:Stark Industries

————————-联系方式—————————-

我有这个代码:

#define MAX_VALUE_FOR_ARRAYS 1000

int main()
{

 long pos = 0; /// this will store the position of the cursor  
 char address_book_content[MAX_VALUE_FOR_ARRAYS];
 char contact_name[MAX_VALUE_FOR_ARRAYS];
 char *string_exists = NULL;
 File *show_address_book = NULL;
 show_address_book = fopen("addressBook.txt", "r");

 printf("Enter the name of the contact you want to search");
 scanf("%s", &contact_name);

 /** I want : when the user inputs a name, the program searches it in the file and if it’s found it prints the rest of the file starting from the line where that name is. So I tried the following **/

 while ( (fgets(address_book_content, MAX_VALUE_FOR_ARRAYS, show_address_book) != NULL)
 {

  if ( (string_exists = strstr(address_book_content, contact_name) != NULL)
  {

   printf("%s", address_book_content);
   pos = ftell(show_address_book);
   fseek(show_address_book, 27, pos); /// 27 in just a random number, I just want it to change the position of the cursor in the file
   printf("%s", address_book_content);

  }

 }

 return 0;

}

例如,当我输入“Tony”时,它只显示:

名字:托尼

我希望它显示联系人“Tony”的全部信息

如果你能帮助我,谢谢

【问题讨论】:

  • 不要使用文字处理器编码,字符串的双引号都是错误的。
  • 我不太明白你在说什么,你能解释一下吗?
  • @TonyStark 你为什么取消我的版本?
  • @TonyStark 您可能在文字处理器或类似程序中复制并粘贴了您的代码,因为它更改了大小写和双引号,因此当前代码无法编译。
  • 那个时候编译没用看问题^^

标签: c arrays string pointers


【解决方案1】:

在

printf(“%s”, address_book_content);
pos = ftell(show_address_book);
fseek(show_address_book, 27, pos); /// 27 in just a random number, I just want it to change the position of the cursor in the file
printf(“%s”, address_book_content);

fseek 不会改变 address_book_content 所以你写了两次相同的东西

您需要从您计算的位置读取文件才能写入您读取的内容,修改address_book_content 是否仍然打印它。或者只是阅读并打印您阅读的下一行:

while ( (fgets(address_book_content, MAX_VALUE_FOR_ARRAYS, show_address_book) != NULL)
 {
  if ( (string_exists = strstr(address_book_content, contact_name) != NULL)
  {
    fputs(address_book_content, stdout); /* fputs rather printf to not write again a \n */
    /* supposing it was the firstname there are 5 lines after to read and print */
    fputs(fgets(address_book_content, MAX_VALUE_FOR_ARRAYS, show_address_book), stdout);
    fputs(fgets(address_book_content, MAX_VALUE_FOR_ARRAYS, show_address_book), stdout);
    fputs(fgets(address_book_content, MAX_VALUE_FOR_ARRAYS, show_address_book), stdout);
    fputs(fgets(address_book_content, MAX_VALUE_FOR_ARRAYS, show_address_book), stdout);
    fputs(fgets(address_book_content, MAX_VALUE_FOR_ARRAYS, show_address_book), stdout);
    break;
  }
}

警告 strstr 不是正确的方法,因为它会捕获包含预期名称的名称,例如名称 IamNotTonyAtAll 匹配 Tony 使用 strstr

当然,每次读取文件以搜索名称时都会非常昂贵...


完整的提案:

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

#define MAX_VALUE_FOR_ARRAYS 1000

int main()
{
  FILE * fp = fopen("addressBook.txt", "r");

  if (fp == NULL) 
    puts("cannot read addressBook.txt");
  else {
    /* use static vars to not take place into the stack */
    static char contact_name[MAX_VALUE_FOR_ARRAYS];
    printf("Enter the name of the contact you want to search : ");

    if (scanf("%s", contact_name) != 1)
      puts("invalid input");
    else {
      static char line1[MAX_VALUE_FOR_ARRAYS];
      static char line2[MAX_VALUE_FOR_ARRAYS];

       /* to have \n at the end like the read lines, it is also possible
          to read the name with fgets but in case of extra spaces at the end it is not found */
      strcat(contact_name, "\n");

      while ((fgets(line1, MAX_VALUE_FOR_ARRAYS, fp) != NULL) &&
             (fgets(line2, MAX_VALUE_FOR_ARRAYS, fp) != NULL))
      {
        if ((strcmp(line1 + /*bypass "First Name : "*/ 13, contact_name) == 0) || /* first name */
            (strcmp(line2 + /*bypass "Last Name : "*/ 12, contact_name) == 0)) { /* last name */
          /* that one */
          fputs(line1, stdout);
          fputs(line2, stdout);
          if (fgets(line1, MAX_VALUE_FOR_ARRAYS, fp) != NULL) {
            fputs(line1, stdout);
            if (fgets(line1, MAX_VALUE_FOR_ARRAYS, fp) != NULL) {
              fputs(line1, stdout);
              if (fgets(line1, MAX_VALUE_FOR_ARRAYS, fp) != NULL) {
                fputs(line1, stdout);
                if (fgets(line1, MAX_VALUE_FOR_ARRAYS, fp) != NULL) {
                  fputs(line1, stdout);
                }
              }
            }
          }
          break;
        }
        else {
          fgets(line1, MAX_VALUE_FOR_ARRAYS, fp);
          fgets(line1, MAX_VALUE_FOR_ARRAYS, fp);
          fgets(line1, MAX_VALUE_FOR_ARRAYS, fp);
          fgets(line1, MAX_VALUE_FOR_ARRAYS, fp);
        }
      }
      fclose(fp);
    }
  }

 return 0;
}

例子:

pi@raspberrypi:/tmp $ ./a.out
Enter the name of the contact you want to search : Tony
First Name : Tony
Last Name : Stark
Address : Malibu
Phone number : 10203044032
E-mail : tony.stark@jarvis.com
Company / Place of work : Stark Industries
pi@raspberrypi:/tmp $ ./a.out
Enter the name of the contact you want to search : Stark
First Name : Tony
Last Name : Stark
Address : Malibu
Phone number : 10203044032
E-mail : tony.stark@jarvis.com
Company / Place of work : Stark Industries
pi@raspberrypi:/tmp $ ./a.out
Enter the name of the contact you want to search : Bruno
First Name : Bruno
Last Name : Pages
Address : somewhere in France
Phone number : 123456789
E-mail : me@hiddenAddress.fr
Company / Place of work : BoUML unlimited

假设 addressBook.txt 包含:

First Name : Tony
Last Name : Stark
Address : Malibu
Phone number : 10203044032
E-mail : tony.stark@jarvis.com
Company / Place of work : Stark Industries
First Name : Bruno
Last Name : Pages
Address : somewhere in France
Phone number : 123456789
E-mail : me@hiddenAddress.fr
Company / Place of work : BoUML unlimited

【讨论】:

  • 谢谢。是的,我注意到它打印了2次,我不明白为什么光标的位置没有改变
  • @TonyStark 您可以使用任何光标位置,address_book_content 不依赖于光标位置,您需要在文件中再次读取
  • 哦,好的,我现在知道了,谢谢。但是如何避免在打印之前总是读取文件(如果可能的话),因为我希望程序自动显示文件的其余部分
  • @TonyStark 如果您只需要搜索 一个 名称就可以了,否则您需要阅读并记住文件,在这种情况下您需要制作一种od 字典,其中键是名称,值是要打印的完整多行
  • 是的,我只想搜索一个名字。
猜你喜欢
  • 1970-01-01
  • 2020-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多