Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   заполнение массива (http://forum.oszone.net/showthread.php?t=157043)

Lisiy_egik 14-11-2009 17:08 1270218

заполнение массива
 
Столкнулся с проблемой:
неком исходном файле содержатся данные в виде:

пн 23.3 55.8 32.5
вт 54.3 23.4
сб 45.7.78.1

или просто:
65.3 74.4 85.2
23.4 54.3
и т.д.

нужно заполнить массив double [7][]
в итоге массив содержит измерения погоды (строки - дни недели. столбцы - измерения)

Вопрос: как заполнить такой массив? Как узнать длину каждой строки массива?

Lisiy_egik 14-11-2009 19:09 1270313

появилась идея - можно запрашивать кол-во столбцов в самом начале.
примерно то, что родилось в голове:

Код:

#include<stdio.h>
#include <conio.h>

void main()
{
#define NR 7;
#define  NC = a;
FILE *f;
int a;

printf("Какое кол-во измерений в день было произведено?(1 2 4 и т.д.)\n");
scanf("%i", &a);

    float weather[NR][NC];
    If ((f = fopen("weather.txt", "rt")) == NULL)
    {
    printf ("не удалось открыть файл \n"
    getch();
    return;
}

int r,c;  // номер строки и столбца

for (r=0; r < NR; r++)
{
    for(c = 0; c  < NC; c++)
    {
            fscanf(f, "%f", wether[r][c]);
    }
}

fclose (f);

}

1. Можно ли так использовать "#define NC = a"? или нужно " = *a" ?
2. Возможно ли обойтись без этой переменной "а"? Чтобы прежде чем заполнять массив, допустим посчитать кол-во элементов первой строки, содержащейся в файле?
3. Каким образом в данной ситуации использовать средства ввода/вывода с++ (cin/cout)
4. Будет ли правильно заполнен массив, если данные в файле выглядят примерно так:

65.4 -98.7 63.5 -46.5 12.3
38.7 38.7 30.8 65.7 74.8
44.5 75.0 -87.0 28.7 34.7
65.4 98.7 -63.5 -46.5 -12.3
38.7 387 30.8 65.7 74.8
-44.5 -75.0 -87.0 28.7 34.7
24.3 70.8 73.2 24.2 09.8

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

Admiral 14-11-2009 19:30 1270332

Lisiy_egik, можно задать структуру файла Бинарные файлы
Единственное что по данной структуре должен быть и заполнен файл, так что если в блокноте где-то пробел был добавлен, программа может с ошибкой считать файл.
В идеале нужно что-б в самой проге и была произведена запись в файл.

Lisiy_egik 15-11-2009 00:53 1270544

решил посмотреть как заполняется массив и вот что вышло:

Код:

#include "stdio.h"
#include "conio.h"
#include "rus8.h"

void main() {

rus();
       
#define NR 7
#define NC 3

        FILE *f;

        float weather[NR][NC];
        int r = 0, c = 0;

        //printf("Введите кол-во измерени        в сутки:");
        //scanf("%i", &a);

        if ((f=fopen("weather.txt", "rt"))==NULL)
        {
                printf("Файл с исходными данными не найден");
                getch();
                return;
        }
        for (r=0; r < NR; r++)
        {
                for(c = 0; c  < NC; c++)
                {
                        fscanf(f, "%f", weather[r][c]);
                }
        }

        fclose (f);

        printf("Данные, загруженные из файла в массив:\n");

        for(r = 0; r < NR; r++)
        {
                for(c = 0; c < NC; c++)
                {
                        printf("%5.1f", weather[r][c]);
                }
        }

        printf("\n \n я завершения нажминие Ввод");
        getch();
}

или если поменять for на while

Код:

#include "stdio.h"
#include "conio.h"
#include "rus8.h"

void main() {

rus();
       
#define NR 7
#define NC 3

        FILE *f;

        float weather[NR][NC];
        int r = 0, c = 0;

        //printf("Введите кол-во измерени        в сутки:");
        //scanf("%i", &a);

        if ((f=fopen("weather.txt", "rt"))==NULL)
        {
                printf("Файл с исходными данными не найден");
                getch();
                return;
        }
                while(r < NR)
{
        while(c<NC)
        {
                fscanf(f, "%f", weather[r][c]);
        }
        c++;
}
r++;

        fclose (f);

        printf("Данные, загруженные из файла в массив:\n");

        for(r = 0; r < NR; r++)
        {
                for(c = 0; c < NC; c++)
                {
                        printf("%5.1f", weather[r][c]);
                }
        }

        printf("\n \n я завершения нажминие Ввод");
        getch();
}

в файле weather.txt содержится:
23.4 55.2 34.5
54.4 35.6 79.8
45.9 65.8 76.7
23.1 45.2 56.3
34.4 98.5 56.6
12.3 23.2 34.1
98.4 87.3 76.2

При компиляции ошибок нет, а вот при запуске выдает:

Необработанное исключение в "0x691c936c (msvcr90d.dll)" в "p2e1.exe": 0xC0000005: Нарушение прав доступа при записи "0x80000000".

В чем моя ошибка?

Ferum01 15-11-2009 12:48 1270780

Цитата:

Цитата Lisiy_egik
нужно заполнить массив double [7][]
в итоге массив содержит измерения погоды (строки - дни недели. столбцы - измерения)
Вопрос: как заполнить такой массив? Как узнать длину каждой строки массива? »

Я бы работал с переменной строки и при заполнии анализировал каждый символ (при анализе символов видно точки, пробелы и цыфры)... Потом есть операторы конца строки и конца фала, поэтому можно, не запрашивать количество измерений.
У меня есть прога похожего плана. Описание программы. Из файла заполненного разными символами выбрать все восеьмеричные комбинации цифр (например "hfdhfhdj45777789rerer jjjj 75 uhh78900987" выбираем 45777789 и 78900987).
Могу текст проги выложить, только там нет комментриев.

Ferum01 15-11-2009 13:04 1270791

так наверное проще всего
for(r = 0; r < NR; r++)
fscanf(f,"%f %f %f\n", weather[r][0], weather[r][1], weather[r][2]);

если данные всегда вида:
23.4 55.2 34.5
54.4 35.6 79.8
45.9 65.8 76.7
23.1 45.2 56.3
34.4 98.5 56.6
12.3 23.2 34.1
98.4 87.3 76.2

Lisiy_egik 15-11-2009 13:11 1270798

Цитата:

Цитата Ferum01
так наверное проще всего
for(r = 0; r < NR; r++)
fscanf(f,"%f %f %f\n", weather[r][0], weather[r][1], weather[r][2]);
если данные всегда вида:
23.4 55.2 34.5
54.4 35.6 79.8
45.9 65.8 76.7
23.1 45.2 56.3
34.4 98.5 56.6
12.3 23.2 34.1
98.4 87.3 76.2 »

в том то и дело, что кол-во элементов в различных строках одинаково, их может быть как 3 так и 5 так 100 в общем N(

Ferum01 15-11-2009 13:53 1270824

Тогда примерно так:

Код:

while(!feof(f))
{
do
{
fscanf(fp1, "%c", &sim[eatt]);
if (sim[eatt]=='\n') break;

do
{
if    ( sim[eatt]=='0' || sim[eatt]=='1' ||
        sim[eatt]=='2' || sim[eatt]=='3' ||
        sim[eatt]=='4' || sim[eatt]=='5' ||
        sim[eatt]=='6' || sim[eatt]=='7' ||
        sim[eatt]=='8' || sim[eatt]=='9' || sim[eatt]=='.')
      { eatt++; fscanf(f, "%c", &sim[eatt]); } else break;
} while (true);
weather[r][]=sim;  r++;
// изначально так было strcpy(number1[num1],sim); можно ли символьную переменную целой присваивать не помню...
eatt=0;
} while (!feof(f));
fscanf(f, "\n");
}
  fclose(f);


Lisiy_egik 15-11-2009 14:00 1270829

Цитата:

Цитата Ferum01
weather[r][]=sim; r++; »

спасиб, ток вопрос - что обозначает эта строка? как я понимаю присваиваем значение sim массиву затем переходим на новую строку, а каким образом присваивается элемент строки? (weather[r][-вот этот-])? и как узнать, коке кол-во элементов в итоге получилось? (эта цифра прост для дальнейшей работы нужна)) )

Ferum01 15-11-2009 14:10 1270836

Цитата:

Цитата Lisiy_egik
спасиб, ток вопрос - что обозначает эта строка? как я понимаю присваиваем значение sim массиву затем переходим на новую строку, а каким образом присваивается элемент строки? (weather[r][-вот этот-])? и как узнать, коке кол-во элементов в итоге получилось? (эта цифра прост для дальнейшей работы нужна)) ) »

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

Количество элементов в строке определяет "eatt" ее наверное надо записать в дополнительный массив массива weather.

Lisiy_egik 15-11-2009 23:24 1271304

я додумался, как определить кол-во элементов в строке. Столкнулся с такой проблемой:
при объявлении массива weather[NR][NC] компилятор сообщает об ошибке, т.к. не может разместить в памяти массив с нулевой размерностью.

вот код, подскажите пожалуйста, если это возможно, как мне все таки создать массив, а только после какого-то момента задать ему размерность

Код:

#include <iostream>
#include <fstream>
#include "rus8.h"
#include "conio.h"
using namespace std;

int main() {

rus();
#define NR 7
#define NC *c
       
        char str[100], ch;
        int i=0,n=0, r, c;
        float weather[NR][NC];

        ifstream in("weather");
        if(!in)
        {
                cout << "Не удалось открыть файл";
                getch();
                return 1;
        }

        in.get(str, 99);
        cout << str <<'\n';
        in.close();

        for(n=0;str[n];n++)
        {
                if(str[n] == ' ')
                {
                        i++;
                        cout << "Найден пробельный символ\n";
                }
                cout << "Символ не является пробелом \n";
        }

        c=i+1;

        cout << "\n Всего символов " << n << " Из них пробельных " << i;

        cout << "\n для завершения нажминие Ввод";
        getch();

        return 0;
}

вот такие ошибки MVS выдает на
Код:

float weather[NR][NC];
main.cpp(15) : error C2100: недопустимое косвенное обращение
main.cpp(15) : error C2057: требуется константное выражение
main.cpp(15) : error C2466: невозможно выделить память для массива постоянного нулевого размера
main.cpp(15) : error C2087: weather: отсутствует индекс

Ferum01 16-11-2009 09:59 1271562

я думаю на #define NC *c ругается, константа не должна меняться, это же не перменная.

Lisiy_egik 16-11-2009 16:37 1271779

все то. что я делал не верно, нужно было через структуру делать, потом читать не символы, а то. что мне точно известно - это значения типа дабл, в общем пойду читать книжки умные и форумы рыть ((

Ferum01 17-11-2009 11:45 1272456

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

Ferum01 19-11-2009 17:52 1274891

Сделал, пользуйте...
Код:

//---------------------------------------------------------------------------

#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <vcl.h>
#pragma hdrstop
#pragma argsused

int main(int argc, char* argv[])
{
char sim[63];  // максимально возможная длина числа
int a, b, eatt=0, numa=0,numb=0,
numstr[1000]; // количество чисел в каждой строке
double number[1000][100]; // массив всех чисел, построчно

  FILE*fp1;

if ((fp1=fopen("1397000.txt", "r"))==NULL)  // считывание чисел из файла 1397000.txt
{
 printf ("not file");
 return 0;
}

do {                //*******
fscanf(fp1, "%c", &sim[eatt]);

do                  //*
if    ( sim[eatt]=='0' || sim[eatt]=='1' || sim[eatt]=='2' || sim[eatt]=='3' ||
        sim[eatt]=='4' || sim[eatt]=='5' || sim[eatt]=='6' || sim[eatt]=='7' ||
        sim[eatt]=='8' || sim[eatt]=='9' || sim[eatt]=='.' || sim[eatt]=='-')
    {eatt++; fscanf(fp1, "%c", &sim[eatt]); } else break;
 while (true);      //*

if (sim[eatt]==' ') {number[numa][numb]=atof(sim); numstr[numa]=numb; numb++; eatt=0;}
if (sim[eatt]=='\n') {number[numa][numb]=atof(sim); numstr[numa]=numb; numb++; eatt=0; numa++; numb=0;}

}                    //*******
while (!feof(fp1));  //*******


  fclose(fp1);

        // ввод всех преобразованных чисел (в double) в файл  1397001.txt
FILE*fp;
fp=fopen("1397001.txt", "w");

for (a=0; a<=numa-1; a++)
{
for (b=0; b<=numstr[a]; b++)
 fprintf (fp,"%f ",number[a][b]);
  fprintf (fp,"\n");
  }

fclose(fp);

        return 0;
}
//---------------------------------------------------------------------------


pva 19-11-2009 21:40 1275108

Не совсем по теме конечно, вот как ещё можно сделать. здесь не хранится в виде *double[7]
Код:

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <iterator>
#include <sstream>
#include <iomanip>
using namespace std;

int main(int argc, char* argv[])
{
    string str1;
    map<string,vector<double> > weather_by_wday;

    while(getline(cin, str1)) // перебираем строчки
    {
        istringstream line_stm(str1);

        if ((line_stm >> str1)) // день недели
        {
            typedef istream_iterator<double,char> istream_iter;
            // копируем в него данные из потока
            copy(istream_iter(line_stm), istream_iter(), back_inserter(weather_by_wday[str1]));
        }
    }

    // теперь всё упорядочено по дням недели
    // weather_by_wday["день недели"] - это вектор данных
    // можно пользоваться им так: weather_by_wday["ВТ"][3] - это будет 3-й вторник
    // допустим надо вывести на экран

    typedef map<string,vector<double> >::iterator map_iter_t;
    unsigned max_data_size = 0;

    // т.к. длины векторов могут быть разные, найдём самый длинный

    string order[7] = {"mon", "tue", "wed", "thr", "fri", "sat", "sun"};

    for(unsigned wday=0; wday<7; ++wday)
    {
        cout << setw(10) << order[wday];
        unsigned size1 = weather_by_wday[order[wday]].size();
        if (max_data_size<size1) max_data_size=size1;
    }

    for(unsigned n=0; n<max_data_size; ++n)
    {
        cout << "\n";
       
        for(unsigned wday=0; wday<7; ++wday)
        {
            cout << setw(10);
            vector<double> &weather(weather_by_wday[order[wday]]);
            if (n<weather.size()) cout << weather[n];
            else cout << "?";
        }
    }

    return 0;
}


Lisiy_egik 20-11-2009 12:52 1275567

Ferum01, pva, спасибо большое, это действительно очень помогло

Lisiy_egik 20-11-2009 13:46 1275608

Цитата:

Цитата Ferum01
#include <vcl.h> »

за что отвечает этот модуль? где его можно взять и как его добавить в библиотеку MVS2008?

Ferum01 20-11-2009 14:58 1275676

Цитата:

Цитата Lisiy_egik
за что отвечает этот модуль? где его можно взять и как его добавить в библиотеку MVS2008? »

vcl.h - библиотека визуальных компонентов, она изначально стоит при создании программ в компиляторе Borland 5.
Вероятно эту библиотеку можно не использовать.


Время: 05:33.

Время: 05:33.
© OSzone.net 2001-