Чтение из файла по столбцам?
вводить в массив значения одного из столбцов. Как ввести всю строку я понимаю, а вот как осуществить ввод, допустим, стобца, который посередине...???
Ламерский вопрос т.к. я и сам ламер:) Имеется текстовый файл в который записано несколько столбцов чисел(стобцы слева направо с пробелом между ними, соответственно) Необходимо в зависимости от выбранного пользователем значения
вводить в массив значения одного из столбцов. Как ввести всю строку я понимаю, а вот как осуществить ввод, допустим, стобца, который посередине...???
Ламерский ответ. Читаешь строку. Ищешь в ней пробелы. Выбираешь подстроку начиная с нужного пробела до следующего. Это и есть элемент из твоего столбца.
Можно извратится еще сильнее:
Заводишь объект TStringGrid. Читаешь строку. Подстрока до первого пробела в столбец 0, следующая до пробела в столбец 1 и.т.д. Таким образом имеешь текстовый файл разбитый на столбцы. Выбираешь нужный и читаешь уже из TStringGrid.
ЗЫ: Если умеешь читать строки, я думаю выбирать подстроки тоже умеешь. Если нужен конкретный код. Свистни.
Ламерский ответ. Читаешь строку. Ищешь в ней пробелы. Выбираешь подстроку начиная с нужного пробела до следующего. Это и есть элемент из твоего столбца.
Можно извратится еще сильнее:
Заводишь объект TStringGrid. Читаешь строку. Подстрока до первого пробела в столбец 0, следующая до пробела в столбец 1 и.т.д. Таким образом имеешь текстовый файл разбитый на столбцы. Выбираешь нужный и читаешь уже из TStringGrid.
ЗЫ: Если умеешь читать строки, я думаю выбирать подстроки тоже умеешь. Если нужен конкретный код. Свистни.
Если можно, то кинь плиз конкретный текст.
Если можно, то кинь плиз конкретный текст.
Примерно так:
//Это все как ты понимаешь легко считается.
//Изврат № 2.
TStringGrid* myGrid;
myGrid = new TStringGrid(NULL);
myGrid->Visible = false; //Это если ты не бросил ее на форму и не хочешь показывать
myGrid->Cols = 3;
while( <есть строки в файле> ) //мне влом писать открытие файла и т.д.
{
fread(buf, strlen(msg)+1, 1, stream);
for(int ColNum = 0;ColNum<3;ColNum++)
{
AnsiString ColStr;
for(int i = 0;i<strlen(msg);i++)
{
if(msg == ' ') break;
ColStr+= AnsiString(msg); //собираем значение столбца
}
i++; //это чтобы пропустить пробел
myGrid->Cells[ColNum][myGrid->Rows] = ColStr;
}
myGrid->Rows++; //следующая строка
}
Если можно, то кинь плиз конкретный текст.
Ничего если пример кину я?
#include<conio.h>
#define MAX 5 //Число элементов в ряду
void main()
{
FILE *in=fopen("input.txt","rb");
int st=3, // номер столбца (считая от нуля)
pos=0,num;
clrscr();
while(!feof(in)) // пока в файле что-то осталось
{
fscanf(in,"%d",&num); // считываем одно число типа int
if(pos==st)printf("%d\n",num); //Если это нужный нам столбец - выводим
pos=++pos%MAX; // Гыыыыы, считаем номер столбца
}
fclose(in);
getch();
}
Пример входного файла:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
Ничего если пример кину я?
#include<conio.h>
#define MAX 5 //Число элементов в ряду
void main()
{
FILE *in=fopen("input.txt","rb");
int st=3, // номер столбца (считая от нуля)
pos=0,num;
clrscr();
while(!feof(in)) // пока в файле что-то осталось
{
fscanf(in,"%d",&num); // считываем одно число типа int
if(pos==st)printf("%d\n",num); //Если это нужный нам столбец - выводим
pos=++pos%MAX; // Гыыыыы, считаем номер столбца
}
fclose(in);
getch();
}
Пример входного файла:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
попробовал написат, не работает, я создал кнопку и Label1, весь код (кроме инклудов и дефайна) поместил в кнопку, вместо printf я сделал label1->caption=num, программа компилируется, но при нажатии на кнопку выдает ошибку, на строке while(!feof(in)). Что неправильно???
попробовал написат, не работает, я создал кнопку и Label1, весь код (кроме инклудов и дефайна) поместил в кнопку, вместо printf я сделал label1->caption=num, программа компилируется, но при нажатии на кнопку выдает ошибку, на строке while(!feof(in)). Что неправильно???
Вроде все правильно, а что за ошибка? Напиши текст.
Вроде все правильно, а что за ошибка? Напиши текст.
Ошибка такая: Project Project1.exe raised exception class EAccessVioltion with message "Access violation at adress 0040175D in module "Project1.exe"".Read of adress 00000012. Process stopped. Use Step or Run to continue.
Ошибка такая: Project Project1.exe raised exception class EAccessVioltion with message "Access violation at adress 0040175D in module "Project1.exe"".Read of adress 00000012. Process stopped. Use Step or Run to continue.
Похоже у тебя файл не открылся. Поставь проверку:
if(in != NULL)
Похоже у тебя файл не открылся. Поставь проверку:
if(in != NULL)
Да. действительно файл тогда не открывался, но теперь, когда файл стал открываться, у в такой программе:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
FILE *in=fopen("i://chisla.txt","rb");
int st=3,
pos=0,num;
while(!feof(in))
{
fscanf(in,"%d",&num);
if(pos==st)
for (int i=0; i<5; i++)
((TLabel*)Form1->FindComponent("Label"+IntToStr(i))) -> Caption = num;
pos=++pos%MAX;
}
fclose(in);
Получается, что во всех четырех label(почему четырех, ведь должно быть три,т.к. в файле три столбца?) получается одно и то же число 14 из исходного файла:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
((TLabel*)Form1->FindComponent("Label"+IntToStr(i))) -> Caption = num;
Ты каждым следующим числом перезаписываешь содержимое label'ов. Именно поэтому там все числа одинаковы и равны последнему найденному числу...
Надо так:
int st=3,i=0,pos=0,num;
while(!feof(in))
{
fscanf(in,"%d",&num);
if(pos==st)((TLabel*)Form1->FindComponent("Label"+IntToStr(++i)))->Caption=num;
pos=++pos%MAX;
}
fclose(in);
От себя добавлю, что #include<conio.h> не нужно. Вот. Я согласен с AlexandrVSmirno - ты наверно просто файл input.txt не создал...
То, что файла действительно не было, это так, но теперь другая проблема... см.выше.
То, что файла действительно не было, это так, но теперь другая проблема... см.выше.
Это ты смотри выше.=))))
Да. действительно файл тогда не открывался, но теперь, когда файл стал открываться, у в такой программе:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
FILE *in=fopen("i://chisla.txt","rb");
int st=3,
pos=0,num;
while(!feof(in))
{
fscanf(in,"%d",&num);
if(pos==st)
for (int i=0; i<5; i++)
((TLabel*)Form1->FindComponent("Label"+IntToStr(i))) -> Caption = num;
pos=++pos%MAX;
}
fclose(in);
Получается, что во всех четырех label(почему четырех, ведь должно быть три,т.к. в файле три столбца?) получается одно и то же число 14 из исходного файла:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
{
FILE *in=fopen("i://chisla.txt","rb");
int st=3,
pos=0,num;
int num_str = 0; //это для номера строки
while(!feof(in))
{
fscanf(in,"%d",&num); //читаешь элемент массива
if(pos==st)
// for (int i=0; i<5; i++) //у тебя i бежит от 0 до 4 вот поэтому и label 4. я думаю, что цикл не нужен вообще
((TLabel*)Form1->FindComponent("Label"+IntToStr(num_str++))) -> Caption = num; //теперь у нас в label элемент из третьего столбца каждой строки
pos=++pos%MAX; //здесь смысл перехода на следующую строку pos=++pos%5
}
fclose(in);
}
В твоем примере у тебя в файле пять столбцов и три строки.
От себя добавлю, что #include<conio.h> не нужно. Вот. Я согласен с AlexandrVSmirno - ты наверно просто файл input.txt не создал...
То, что файла действительно не было, это так, но теперь другая проблема... см.выше.
То, что файла действительно не было, это так, но теперь другая проблема... см.выше.
Посмотри мое предыдущее. Там я тебе код малость поправил.
Посмотри мое предыдущее. Там я тебе код малость поправил.
Спасибо, с этим я разобрался, там цикл и вправду не нужен, а просто i++, но теперь у меня еще проблемка... Я хочу чтобы из файла с тремя столбцами считывались к примеру 2 и 3 столбец в массив, а потом по этому массиву строился график... я написал такую вещь, предварительно добавив chart и установив там series1 на lines:
при нажатии кнопки:
FILE *in=fopen("i://chisla.txt","rb");
int st1=3,st2=2,i=0,j=0,pos=0,num1,num2;
int a[3];
int b[3];
while(!feof(in))
{
fscanf(in,"%d",&num1);
if(pos==st1)
{
i++;
a= num1;
//((TLabel*)Form1->FindComponent("Label"+IntToStr(i))) -> Caption = a;
}
if(pos==st2)
{
j++;
b[j]=num2;
}
pos=++pos%MAX;
}
fclose(in);
for(i=1;i<4;i++)
Series1->Add(a,b,clBlue);
}
программа компилируется, но у точек координаты правильные только по оси икс, то есть правильные числа только у массива a, а у b получаются огромные семизначные или еще больше значения... в чем тут дело? может я неправильно считываю значения в массив b[2]?
Спасибо, с этим я разобрался, там цикл и вправду не нужен, а просто i++, но теперь у меня еще проблемка... Я хочу чтобы из файла с тремя столбцами считывались к примеру 2 и 3 столбец в массив, а потом по этому массиву строился график... я написал такую вещь, предварительно добавив chart и установив там series1 на lines:
при нажатии кнопки:
FILE *in=fopen("i://chisla.txt","rb");
int st1=3,st2=2,i=0,j=0,pos=0,num1,num2;
int a[3];
int b[3];
while(!feof(in))
{
fscanf(in,"%d",&num1);
if(pos==st1)
{
i++;
a= num1;
//((TLabel*)Form1->FindComponent("Label"+IntToStr(i))) -> Caption = a;
}
if(pos==st2)
{
j++;
b[j]=num2;
}
pos=++pos%MAX;
}
fclose(in);
for(i=1;i<4;i++)
Series1->Add(a,b,clBlue);
}
программа компилируется, но у точек координаты правильные только по оси икс, то есть правильные числа только у массива a, а у b получаются огромные семизначные или еще больше значения... в чем тут дело? может я неправильно считываю значения в массив b[2]?
Ты num2 не заполняешь ни как. Что там должно быть?. Вот поэтому у тебя в массиве b и черте-что.
ЗЫ: Я думаю что num2 тебе нужно заменить на num1. Ведь если позиция совпадает со 2 столбцом его нужно запомнить в массив a, а если с 3,то в массив b. А числа ты читаешь все время в num1.
Ты num2 не заполняешь ни как. Что там должно быть?. Вот поэтому у тебя в массиве b и черте-что.
ЗЫ: Я думаю что num2 тебе нужно заменить на num1. Ведь если позиция совпадает со 2 столбцом его нужно запомнить в массив a, а если с 3,то в массив b. А числа ты читаешь все время в num1.
Да, все так и стоило сделать, огромное спасибо, все работает, но... теперь такая проблема: при построении графика по точкам в chart, несмотря на то что я ввожу две одинаковых точки ( координаты совпадают), на графике показывает их в разных местах, т.е. одну после другой... и таким образом по оси икс у меня получается, к примеру два значения 3... как от этого избавится? И есть ли какая-нибудь настройка в chart, чтобы сгладить острые углы на графике?
Да, все так и стоило сделать, огромное спасибо, все работает, но... теперь такая проблема: при построении графика по точкам в chart, несмотря на то что я ввожу две одинаковых точки ( координаты совпадают), на графике показывает их в разных местах, т.е. одну после другой... и таким образом по оси икс у меня получается, к примеру два значения 3... как от этого избавится? И есть ли какая-нибудь настройка в chart, чтобы сгладить острые углы на графике?
Про chart я не знаю, а так пробежись еще раз по массивам a и b и выкинь одинаковые точки. Я правда слету код не напишу. Попробуй сам. Не получится - свисни.
Про chart я не знаю, а так пробежись еще раз по массивам a и b и выкинь одинаковые точки. Я правда слету код не напишу. Попробуй сам. Не получится - свисни.
Все равно спасибо, но пробежаться по массивам и выкинуть одинаковые точки не совсем верно, т.к. у точек могут быть только одинаковые абсциссы, а ординаты разные, поэтому придется придумывать что то еще... Спасибо за помощь!
Ты num2 не заполняешь ни как. Что там должно быть?. Вот поэтому у тебя в массиве b и черте-что.
ЗЫ: Я думаю что num2 тебе нужно заменить на num1. Ведь если позиция совпадает со 2 столбцом его нужно запомнить в массив a, а если с 3,то в массив b. А числа ты читаешь все время в num1.
Теперь у меня возникла проблема считывания, только нужных сток... то есть текстовый файл начинается не сразу со столбцов, а сначал идет пара строк которые не представляют интереса, например:
s=12 p=35 z=70
z1=23 z2=40 z34=55
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
Теперь я думаю легко разобраться в чем проблема.