На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Модераторы: Qraizer
  
> Вопрос по чтению - записи вектора , Вопрос по чтению - записи вектора
    Здравствуйте,
    заполняется вектор1 с массивом структур, сохраняю в файл,
    начинаю считывать в вектор2 - выдаёт количество элементов плюс один.
    Кто-нибудь может объяснить, что не так, вот код:

    ExpandedWrap disabled
      #include "stdafx.h"
      #include <fstream>
      #include <iostream>
      #include <vector>
       
      using namespace std;
       
      struct MyStruct
      {
          char* city;
          int number;
      };
       
      int _tmain(int argc, _TCHAR* argv[])
      {
          vector <MyStruct> vector1, vector2;
          MyStruct struct1, struct2;
          int i = 0;
          for (i = 0; i < 10; i++)
          {
              struct1.city = "City";
              struct1.number = i+1000;
              vector1.insert(vector1.end(), struct1);
          }
          FILE *file;
          file = fopen("cpp2.dat","wb");
          for (i = 0; i < vector1.size(); i++)
              fwrite(&vector1[i], sizeof(vector1[i]), 1, file);
          fclose(file);
       
          i = 0;
          file = fopen("cpp2.dat","rb");
          while(!feof(file))
          {
              fread(&struct2, sizeof(struct2), 1, file);
              vector2.insert(vector2.end(), struct2);
          }
          fclose(file);
       
          for (i = 0; i < vector2.size(); i++)
              cout << vector2[i].city << "  " << vector2[i].number << endl;
       
          system("pause");
          return 0;
      }
      Цитата Rustam @
      Кто-нибудь может объяснить, что не так, вот код:

      Проверь, что у тебя возвращает fread:

      size_t n = fread(.......);
        Потому что feof() выдаёт состояние потока, а не анализирует позицию в файле. Состояние встанет в EOF не после чтения последней структуры, а при попытке чтения за ней.

        P.S. В программе две грубых ошибки:
        1. полю с типом char* присваивается строковый литерал;
        2. в файл пишется указатель вместо строки.
          добавил size_t, теперь нормально выводит количество

          ExpandedWrap disabled
                for (i = 0; i < t; i++)
                {
                    size_t n = fread(&struct2, sizeof(struct2), 1, file);
                    if (n==1)
                        vector2.insert(vector2.end(), struct2);
                }


          Добавлено
          Цитата Qraizer @
          Потому что feof() выдаёт состояние потока, а не анализирует позицию в файле. Состояние встанет в EOF не после чтения последней структуры, а при попытке чтения за ней.

          P.S. В программе две грубых ошибки:
          1. полю с типом char* присваивается строковый литерал;
          2. в файл пишется указатель вместо строки.

          А почему грубые ошибки, если всё работает как надо?
            Мдя кто тя учил так программировать? Не бабушка нет? :D

            Добавлено
            Что это?!
            struct1.city = "City";
            Надо
            strcpy(struct1.city, "City");
            Да естесно предварительно там память выделиьь для city
              Цитата Rustam @
              А почему грубые ошибки, если всё работает как надо?
              1. Работает на честном слове. Строковые литералы являются константами, как и литералы любых других типов. "City" – это константа, и её тип const char[5]. Присваивая его указателю на неконстанту, ты можешь – и наверняка будешь в более сложной программе – его менять, что будет иметь неопределённый эффект. От "ничего не поменялось" до "Программа выполнила невыполнимое и допустила недопустимое", а где-то между ними "какого хрена я меняю одну структуру, а меняются сразу все???".
              2. Это работает в одной программе. А вот попробуй писать в одной, читать в другой.
                Цитата Qraizer @


                Насчёт char* понятно,
                а как я могу записать вектор в файл, это же объект, он у меня только как указатель записывается
                как строку вектор можно записать с какими нибудь разделителями с помощью ofstream и считать ifstream ?
                  Цитата Rustam @
                  Насчёт char* понятно,
                  а как я могу записать вектор в файл, это же объект, он у меня только как указатель записывается


                  Объяви структуру как

                  ExpandedWrap disabled
                    struct MyStruct
                    {
                        char city[64];
                        int number;
                    };
                     
                    .......
                     
                        for (i = 0; i < 10; i++)
                        {
                            strcpy(struct1.city, "City");
                            struct1.number = i+1000;
                            vector1.insert(vector1.end(), struct1);
                        }
                    как-то так получилось,
                    теперь и читает и записывает в разных программах

                    такой код пойдёт ?

                    ExpandedWrap disabled
                          vector <MyStruct> vector1, vector2;
                          MyStruct struct1, struct2;
                          int i = 0;
                          for (i = 0; i < 10; i++)
                          {
                              strcpy(struct1.city,"City");
                              struct1.number = i+1000;
                              struct1.fl = i + 10;
                              vector1.insert(vector1.end(), struct1);
                          }
                       
                      // запись
                          ofstream fout("cpp2.txt");
                          int t = vector1.size();
                          for (i = 0; i < t; i++)
                              fout << vector1[i].city << "|" << vector1[i].number << "|" << vector1[i].fl << endl;
                          fout.close();
                       
                      // чтение
                          ifstream fin("cpp2.txt");
                          i = 0;
                          string line;
                          while (fin)
                          {
                              getline(fin, line, '|');
                              if (line.size() == 0)
                                  break;
                              const char *ptr = line.c_str();
                              strcpy(struct2.city, ptr);
                       
                              getline(fin, line, '|');
                              struct2.number = stoi(line);
                       
                              getline(fin, line);
                              struct2.fl = stof(line);
                       
                              vector2.insert(vector2.end(), struct2);
                          }
                          fin.close();
                       
                          for (i = 0; i < vector2.size(); i++)
                              cout << vector2[i].city << "  " << vector2[i].number << "  " << vector2[i].fl << endl;
                      Цитата Rustam @
                      такой код пойдёт ?

                      А MyStruct как объявлена?
                        Цитата Олег М @


                        ExpandedWrap disabled
                          struct MyStruct
                          {
                              char city[30];
                              int number;
                              float fl;
                          };
                          Искал, искал и, наконец, нашёл, что город Бад-Мюнстер-на-Штайн-Эбернбурге не влезет в массив. :blush:
                            Цитата Славян @
                            Искал, искал и, наконец, нашёл, что город Бад-Мюнстер-на-Штайн-Эбернбурге не влезет в массив.

                            Мог бы не искать, а просто сказать, что лучше здесь использовать функцию strncpy


                            ExpandedWrap disabled
                              static const size_t _city_ln = 30;
                              struct MyStruct
                              {
                                  char city[_city_ln + 1];
                                  int number;
                                  float fl;
                              };
                              ........
                              MyStruct struct1 = {0};
                              .....
                               
                              strncpy(struct1.city, "City", _city_ln);
                              Всем спасибо!
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0429 ]   [ 16 queries used ]   [ Generated: 23.04.24, 18:00 GMT ]