C, файл вывода показывает зашифрованное изображение в начале вывода? - PullRequest
0 голосов
/ 26 апреля 2019

Предполагается, что программа должна показать меню, а пользователь должен сделать выбор, выбрав указанное число.

Программы работают хорошо, но когда дело доходит до чтения содержимого файла, оно начинается с некоторых символов cryptec, а затемэто показывает содержание файла.Я испробовал все решения, например, использование другой функции reding для файла, но результат тот же

, почему отображаются эти символы?и откуда они берутся?

The image below explain the encryptec symbols in the begining of the output

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
//functions protoype
void Menu(FILE *file);
void Add_Number(FILE*file);
void Show_Numbers(FILE *file);
void Search_Number(FILE *file);


//Define a struct
typedef struct {
    char firstName[20];
    char lastName[20];
    unsigned long number ;
}person;


//Main program
int main()
{
    FILE *file = NULL;
    //file = fopen("contacts.txt", "a+");
    Menu(file);
     return 0;
}


void Add_Number(FILE *file)
{
    person newUser;

    file = fopen("contacts.txt", "a");
    if (file != NULL)
    {
    printf("NOM:\n");
    scanf("%s",newUser.firstName);
    fflush(stdin);

    printf("Prenom:\n");
    scanf("%s",newUser.lastName);
    fflush(stdin);

    printf("Numero:\n");
    scanf("%lu",&(newUser.number));
    fflush(stdin);

    fprintf(file, "\n%s\t%s\t%lu", newUser.firstName, newUser.lastName, newUser.number);
    fflush(stdin);
    printf("Success");

    }

    else
    {
        printf("Erreur d'ouverture de fichier");
        exit(-1);
    }
    fclose(file);
}


void Show_Numbers(FILE*file)//FILE *file)
{
    person user;
    char s[100];
    file = fopen("contacts.txt", "a+");
    printf("%s", user.firstName);

    if (file != NULL)
    {
        fseek(file,1,0);
         while (fgets(s,1000,file)!=NULL)
         {
             printf("%s",s);
         }


        //while (fgets(test, 100, file) != NULL /*EOF*/) // On lit le fichier tant qu'on ne reçoit pas d'erreur (NULL)
           /* {
                printf("%s\n", test); // On affiche la chaîne qu'on vient de lire
            }*/

        fclose(file);


/*
            fg(file, "%s %s %lu\n", test);//, user.lastName, user.number);
            printf("Nom: %s\t\t", test);//user.firstName);
         //   printf("Prenom: %s\t\t", user.lastName);
          //  printf("Numero: %lu\n", user.number);*/


    }
     else
    {
        printf("Erreur d'ouverture de fichier");
        exit(-1);
    }
  fclose(file);
}


void Search_Number(FILE *file)
{
    file = fopen("contacts.txt", "a+");
    char userToFined[20];
    person user;
    //test if file not NULL
    if(file != NULL)
    {
            //input
        puts("saisir le numero a chercher\n");
        gets(userToFined);

        //read from the begging
        rewind(file);
        do
        {
            fscanf(file, "%s %s %lu", user.firstName, user.lastName, &user.number);
        }
        while (user.firstName != userToFined && !feof(file));

        if(user.firstName == userToFined)
        {
            printf("Success ! %s est trouve\n", user.firstName);
            printf("Son est prenom: %s\t\t", user.lastName);
            printf("Son numero est: %lu\n", user.number);
        }
        else
        {
            printf("%s est introuvable", userToFined);
        }
    }
    else
    {
        printf("Erreur d'ouverture de fichier");
        exit(-1);
    }
    fclose(file);
}


void Menu(FILE *file)
{
int choice;
    do
    {
        puts("\n************************************************************\n\t\t BIENVENUE \t\t\n************************************************************");
        puts("\t \t **Choisir votre choix**\t \t\n");
        puts("---1---  Ajouter un nouveau contact\n");
        puts("---2---  Afficher le repertoire\n");
        puts("---3---  rechercher un numero\n");
        puts("---4---  Ajouter un nouveau contact\n");
        puts("Votre Choix:");
        scanf("%d", &choice);

        switch (choice)
        {
        case 1:
            Add_Number(file); // Add user
            break;
        case 2:
            Show_Numbers(file); //Show repository
            break;
        case 3:
            Search_Number(file); //Search User
            break;
        case 4:
            exit(0);
            break;
        default:
           printf("Choix Invalid");
            break;
    }

    } while (choice != 4);
}

Ответы [ 2 ]

1 голос
/ 27 апреля 2019

Функция Show_Numbers() имеет ряд проблем:

void Show_Numbers(FILE*file)  //<<< WHY IS file AN ARGUMENT?
{
    person user;                         // <<<< DELETE THIS
    char s[100];
    file = fopen("contacts.txt", "a+");  // <<<< OPEN FOR READ-ONLY
    printf("%s", user.firstName);        // <<<< DELETE THIS

Переменная user унифицируется, а затем используется только при попытке печати инициализированного значения.Таким образом, две указанные строки не имеют никакого значения и являются причиной нежелательного вывода.

Файл открыт для добавления, но никогда не записывается в.

Передача file в качестве аргумента служитне имеет смысла, если вы открываете и закрываете файл локально.Вместо этого используйте:

     FILE* file = fopen( "contacts.txt", "r" ) ;

и не передавайте аргумент.

Затем позже:

     while (fgets(s,1000,file)!=NULL)
     {
         printf("%s",s);
     }

Вы читаете куски по 1000 символов в массив из 100 символов.

Наконец, но не так критично, в конце функции вы излишне закрываете файл, который был ранее закрыт в функции.

  fclose(file);
}
0 голосов
/ 27 апреля 2019

user.firstName не инициализируется в Show_Numbers при печати. Доступ к неинициализированной памяти - неопределенное поведение. В этом случае ваша программа интерпретирует любые значения, которые лежат в этих адресах памяти, как строку символов и печатает это. Так уж получилось, что «× Í = ÿp ■` ».

person user;
printf("%s", user.firstName); // uninitialized, may print garbage

Также, fgets(s,1000,file) может записывать вне буфера. s только 100 символов, а не 1000.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...