Есть файл, в котором хранятся записи вида A:1:2:3.33:4:5 Причём каждая новая запись с новой строчки Где А-текст 1,2,4,5 - целые числа. Причём число 5 может достигать нескольких десятков тысяч. 3.33 - дробное число. Нужно написать прогу, чтоб она убирала текстовую часть (т.е. А). Объясняю как это нужно делать. Пройтись от числа 5 до двоеточия, которое стоит перед первым числом (1). Т.е. просто считать двоеточия, проходя каждую строчку и когда их станет 5(пять) нужно остановиться. Записать результат нужно в новый файл. Т.е. поясню ещё раз - input.txt output.txt Спасибо за помощь, ЗЫ. название темы получше придумать не смог :/
не проше через strtok() разбить строку? просто шас под рукой нет компилятора , а так вот набросал : Code: #include<stdio.h> #include<string.h> int main(int argc , char *argv[]) { char src[] = "text:123:15:17:20:30:5"; char *pch; FILE *fp; fp = fopen("test.txt" , "w+"); if(fp == NULL) { return -1; } pch = strtok(src , ":"); while(true) { pch = strtok(NULL , ":"); if(pch == NULL) { break; } fputs(pch , fp); fputs(":" , fp); } fclose(fp); return 0; } файл должен содержать 123:15:17:20:30:5: чего-то ступил лучше fprintf использовать Code: fprintf(fp , ":%s" , pch);
дафайте и я набросаю 8) Бил прямо тут так что извиняй за ошибки если что 8))) ...но идея должна быть понятна! Функция h_f вытаскивает подстроку по ее номеру где определена строка делимитеров(разделителей) Code: #include "stdio.h" #include "string.h" #include "stdlib.h" int h_f(char *sourcestr,char *deststr,int nelement,char *delimiterStr,int mode) { int i; int mcnt; char tstr[300]; int flrez=0; int pstr=0; int prepfl; *(deststr)=0; if(strchr(delimiterStr,*(sourcestr))!=0) prepfl=0; else prepfl=1; for(i=0,mcnt=1,flrez=0,prepfl=0;*(sourcestr+i)!=0;i++) { if(strchr(delimiterStr,*(sourcestr+i))!=NULL) { if(mode==0) { if(prepfl!=0) { if(mcnt<=nelement) mcnt++; else break; } prepfl=0; } else { if(mcnt<=nelement) mcnt++; else { flrez=1; break; } } } else { if(mcnt==nelement) { *(deststr+pstr)=*(sourcestr+i); pstr++; flrez=1; } prepfl=1; } } *(deststr+pstr)=0; return flrez; } int main() { FILE *f1,*f2; char tstr[200]; char dstr[50]; int ind=0; int i,j,fl,z; if((f1=fopen("input.txt","rt"))!=0) { if((f2=fopen("output.txt","w+b"))!=0) { do { fgets(tstr,49,f1); for(i=1,z=0;h_f(tstr,dstr,i,":\r\n",1)==1;i++) // ИЗМЕНЕНО { for(j=0,fl=0;*(dstr+j)!=0 && fl==0;j++) if(!(*(dstr+j)>='0' && *(dstr+j)<='9')) if(!(*(dstr+j)=='.')) fl=1; if(fl==0) { if(z>0) fprintf(f2,":"); else z++; fprintf(f2,"%s",dstr); } } fprintf(f2,"\r\n"); } while(!feof(f1)) ; fclose(f2); } fclose(f1); } return 0; }
Ни то, ни другое не работает Скачал я с торента Borland 3.1 у delimiter'a ругается на 'eof' у _antony на 'true'
проверил все работает (mfc проект) Code: int h_f(char *sourcestr,char *deststr,int nelement,char *delimiterStr,int mode) { int i; int mcnt; char tstr[300]; int flrez=0; int pstr=0; int prepfl; *(deststr)=0; if(strchr(delimiterStr,*(sourcestr))!=0) prepfl=0; else prepfl=1; for(i=0,mcnt=1,flrez=0,prepfl=0;*(sourcestr+i)!=0;i++) { if(strchr(delimiterStr,*(sourcestr+i))!=NULL) { if(mode==0) { if(prepfl!=0) { if(mcnt<=nelement) mcnt++; else break; } prepfl=0; } else { if(mcnt<=nelement) mcnt++; else { flrez=1; break; } } } else { if(mcnt==nelement) { *(deststr+pstr)=*(sourcestr+i); pstr++; flrez=1; } prepfl=1; } } *(deststr+pstr)=0; return flrez; } void CSsDlg::OnButton1() { // TODO: Add your control notification handler code here FILE *f1,*f2; char tstr[200]; char dstr[50]; int ind=0; int i,j,fl,z; if((f1=fopen("input.txt","rt"))!=0) { if((f2=fopen("output.txt","w+b"))!=0) { do { if(fgets(tstr,49,f1)>0) { for(i=1,z=0;h_f(tstr,dstr,i,":\r\n",1)==1;i++) //ИЗМЕНЕНО! { for(j=0,fl=0;*(dstr+j)!=0 && fl==0;j++) if(!(*(dstr+j)>='0' && *(dstr+j)<='9')) if(!(*(dstr+j)=='.')) fl=1; if(fl==0) { if(z>0) fprintf(f2,":"); else z++; fprintf(f2,"%s",dstr); } } } fprintf(f2,"\r\n"); } while(!feof(f1)) ; fclose(f2); } fclose(f1); } } Input.txt Code: A:1:2:3:4.44:5:6 Output.txt Code: 1:2:3:4.44:5:6
ууу... жесть какая... а не проще было бы считать фаил посимвольно в массив и сравнить по кодам отдельно взятых символов
а в чем упрощение Алгоритм 1. считывается строка 2. считываем подстроку по счетчику 3. проверяем является ли полностью цифровой 4. если да пишем в файл 5. переходим к пункту 2 если подстрока последняя переходим к пункту 1 8)
В ворде нажми альт, выдели горизонтальный блок, который не нужен. Правда если файл громадный замучаешься листать и проще написать программу.
ребята, ваши посты меня реально напугали о_0 ТАК усложнить задачу могут лишь избранные и все они ч0то уже отпостили Sylar: 1)качаешь HtmlLerz (набор прог для резки текста) _http://softsearch.ru/programs/ 203-007-htmllerz-pro-download.shtml 2)запускаешь CutText 3)Start Cutoff - в этом окошки стираешь все И жмешь Ентер (те символ начала фрагмента, который надо вырезать, будет символ переноса строки) 4)End Cutoff - тут символ конца фрагмента те двоеточие : 5)Replace TO - на что заменить удаленный фрагмент - тут тоЖ Ентер вот и все - прога вырежет все фрагменты от начала строки до первого двоеточия и все будет ха-ра-шо
2Karantin Текстовая часть в каждой строке разной длины. 2devton В текстовой части тоже могут быть двоеточия... Короче реально работал только вариант Delimiter'a
2 Karantin 2 devton было написано: Code: Нужно написать прогу, чтоб она убирала текстовую часть (т.е. А)..............
А если так... Code: #include <stdio.h> #include <string.h> void main() { FILE *fpin, *fpout; if((fpin = fopen("input.txt", "r")) == NULL) return; if((fpout = fopen("output.txt", "w")) == NULL) return; int i, dc, len, oc = 0; char in[100]; char out[100]; while(fgets(in, 100, fpin)) { len = strlen(in); dc = oc = 0; for(i = 0; i < len; i++) { if(in[len - i - 1] == ':') dc++; if(dc > 4) break; out[oc] = in[len - i - 1]; oc++; } out[oc] = 0; fputs(strrev(out), fpout); strcpy(out, ""); } fclose(fpin); fclose(fpout); }
мы видим что ты пишешь в out и считаешь поля и после 5 полей ничего не запишешь, но это несколько не соответствует задаче! ... давайте представим любителей прямой записи из одного массива в другой ВАРИАНТ 1 Ablablabla:1..... даже если будет проверка на первом же символе мы определяем что 1-е поле текстовое .... и как итог имеем простую логику ! ВАРИАНТ 2 3.12А:1.... и вот уже любители прямой записи чешут репу как они стерут 3.12 обнаружив следующий символ 'А' .... и их упрощения идут в мусорку строем!
в моем даже не останавливается если будет хоть 20-ть блоков! Зачем уменьшать область применимости программы?
Ты прав, тогда зайдем с другой стороны.. Code: #include <stdio.h> #include <string.h> char *get_fstr(char *in, char div) { int i, j, start, end, skip, oc = 0; char out[100]; for(i = 0; i < strlen(in); i++) { start = i; for(int j = 0; i + j < strlen(in); j++) { if(in[i + j] == div || i + j + 1 == strlen(in)) { end = i + j; break; } if((in[i + j] > 64 && in[i + j] < 91) || (in[i + j] > 96 && in[i + j] < 123)) skip = 1; } if(start == end) skip = 1; if(!skip) for(int j = start; j <= end; j++, oc++) out[oc] = in[j]; skip = 0; i = end; } out[oc] = 0; return out; } void main() { FILE *fpin, *fpout; if((fpin = fopen("input.txt", "r")) == NULL) return; if((fpout = fopen("output.txt", "w")) == NULL) return; char in[100]; while(fgets(in, 100, fpin)) fputs(get_fstr(in, ':'), fpout); fclose(fpin); fclose(fpout); } Кроме пропуска блоков с буквами, игнорирует пустые блоки( :: ) Вот пример работы input.txt la:la13:11:133:0.00:7:10288:cf:5658:45h456:78 bla!b13:0:1008:0.87:0:13154:77::97 output.txt 11:133:0.00:7:10288:5658:78 0:1008:0.87:0:13154:77:97