Advertisement
Guest User

Untitled

a guest
Jul 26th, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.40 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. #define MAXROWS 10000
  7. #define MAXCOLS 1000
  8. #define START_YEAR 1900
  9. #define DATE_COLUMNS 3
  10.  
  11. int reportRows, reportColumns, itemsColumns = 4;
  12. const char *reportFileName = "montly_report.csv";
  13.  
  14. struct Date //Datata na koja e kupen produktot
  15. {
  16. int day;
  17. int month;
  18. int year;
  19. };
  20.  
  21. struct Item //Stavkata ovojpat ke ima ogranicen broj na koloni
  22. {
  23. char *name; //imeto na stavkata
  24. int quantity; //kolicina
  25. int price; //cena
  26. Date *date; //data na kupuvanje
  27. };
  28.  
  29. struct Category //една колона од montly_report.csv
  30. {
  31. char *name; //ime na kategorijata
  32. Item items[MAXROWS]; //(референца кон табела со ставки)
  33. int numItems; //број на ставки
  34. char **values; //(низа од ќелии во таа колона)
  35. unsigned int isCategory; //булова вредност за тоа дали категоријата содржи табела со ставки
  36. };
  37.  
  38. int countRows(const char *file_name) //broi linii od dadoteka
  39. {
  40. FILE *f = fopen(file_name, "r+");
  41. int count = 0;
  42. char buff[MAXCOLS];
  43.  
  44. while (fgets(buff, MAXCOLS, f) != NULL)
  45. {
  46. count++;
  47. }
  48.  
  49. fclose(f);
  50. return count;
  51. }
  52.  
  53. int countColumns(char *s, char separator) //broi zborovi od linija
  54. {
  55. int count = 0;
  56. while (*s != '\0')
  57. {
  58. if (*s == separator)
  59. {
  60. count++;
  61. }
  62. s++;
  63. }
  64. return ++count;
  65. }
  66.  
  67.  
  68. char **words(char *s, char sep, int numCols) //separate the line to words, using the number of columns
  69. {
  70. char **seps = new char*[numCols];
  71. char *nextStart = s;
  72. for (int i = 0; i < numCols; i++)
  73. {
  74. while (*s != sep && *s != '\n' && *s != '\0')
  75. {
  76. s++;
  77. }
  78. int len = s - nextStart;
  79. seps[i] = new char[len];
  80. strncpy(seps[i], nextStart, len);
  81. seps[i][len] = '\0';
  82. nextStart = ++s;
  83. }
  84. return seps;
  85. }
  86.  
  87. void initializeItems(Category *category) //so ovaa funkcija se otvora tabelata so stavki za da se inicijaliziraat
  88. {
  89. char *tempName = new char[strlen(category->name)+1];
  90. strcpy(tempName, category->name);
  91. tempName[strlen(tempName)] = '\0';
  92. FILE *f = fopen(strcat(tempName, ".csv"), "r");
  93. if (f == NULL) //dokolku ne postoi ne pravi nishto
  94. {
  95. category->isCategory = 0; //se oznacuva deka ne e "kategorija"
  96. return;
  97. }
  98. category->isCategory = 1;
  99. category->numItems = 0;
  100. char buff[MAXCOLS];
  101. fgets(buff, MAXCOLS, f); //prvata redica so iminjata se preskoknuva
  102. char *line;
  103. while ((line = fgets(buff, MAXCOLS, f)) != NULL)
  104. {
  105. char **itemSubs = words(line, ',', itemsColumns); //se deli linijata na niza od stringovi
  106. category->items[category->numItems].name = itemSubs[0]; //ime na stavka
  107. category->items[category->numItems].quantity = atoi(itemSubs[1]); //kolicina
  108. category->items[category->numItems].price = atoi(itemSubs[2]); //cena
  109. category->items[category->numItems].date = (Date*)malloc(sizeof(Date)); //data na kupuvanje
  110. char **dateSubs = words(itemSubs[3], '.', DATE_COLUMNS);
  111. category->items[category->numItems].date->day = atoi(dateSubs[0]); //den
  112. category->items[category->numItems].date->month = atoi(dateSubs[1]); //mesec
  113. category->items[category->numItems].date->year = atoi(dateSubs[2]); //godina
  114. category->numItems++; //realniot broj na stavki se zgolemuva
  115. }
  116. fclose(f);
  117. }
  118.  
  119. Category **initializeCategory()
  120. {
  121. reportRows = countRows(reportFileName);
  122. FILE *f = fopen(reportFileName, "r+");
  123. char buff[MAXCOLS];
  124. char *line = fgets(buff, MAXCOLS, f);
  125. reportColumns = countColumns(line, ',');
  126. Category **categories = new Category*[reportColumns]; //kategorii kolku sto imam koloni vo dadotekata , niza od tolku kategorii
  127. if (line != NULL)
  128. {
  129. char **splited = words(line, ',', reportColumns);
  130. for (int i = 0; i < reportColumns; i++)
  131. {
  132. categories[i] = (Category*)malloc(sizeof(Category));
  133. categories[i]->values = new char*[reportRows-1];
  134. categories[i]->name = new char[strlen(splited[i])+1]; //name - string
  135. strcpy(categories[i]->name, splited[i]);
  136. categories[i]->name[strlen(splited[i])] = '\0';
  137. initializeItems(categories[i]);
  138. }
  139. }
  140. int j = 0;
  141. while ((line = fgets(buff, MAXCOLS, f)) != NULL)
  142. {
  143. char **splited = words(line, ',', reportColumns);
  144. for (int i = 0; i < reportColumns; i++)
  145. {
  146. categories[i]->values[j] = new char[strlen(splited[i])+1];
  147. strcpy(categories[i]->values[j], splited[i]);
  148. categories[i]->values[j][strlen(splited[i])] = '\0';
  149. }
  150. j++;
  151. }
  152. fclose(f);
  153.  
  154. return categories;
  155.  
  156. }
  157.  
  158. char **insertInto(char **src, const char *colName, int index, int numColumns)
  159. {
  160. char **dest = new char*[numColumns + 1]; //нова ноза од категории со должина поголема за 1 од претходната
  161. for (int i = 0; i < index; i++) //se dodeka ne sum stignala do indeksot gi dodeluvam istite kategorii od starata vo novata niza
  162. {
  163. dest[i] = new char[strlen(src[i])+1];
  164. strcpy(dest[i], src[i]);
  165. dest[i][strlen(src[i])] = '\0';
  166. }
  167. dest[index] = new char[strlen(colName)+1]; //koga ke stignam, tuka ja stavam novata kategorija so soodvetnoto ime
  168. strcpy(dest[index], colName);
  169. dest[index][strlen(colName)] = '\0';
  170. for (int i = index + 1; i < numColumns + 1; i++)
  171. {
  172. dest[i] = new char[strlen(src[i-1])+1]; //prodolzuvam od pozicija i=index+1 i od starata niza gi dodeluvam onie na pozicija i-1 vo novata
  173. strcpy(dest[i], src[i - 1]);
  174. dest[i][strlen(src[i-1])] = '\0';
  175. }
  176. return dest; //nova niza od kategorii / nova kolona
  177. }
  178.  
  179. int calcLen(char **src, int numColumns) //Вкупна должина на низа од стрингови, "Jas" "ti" "Toj" = 8
  180. {
  181. int len = 0;
  182. for (int i = 0; i < numColumns; i++)
  183. {
  184. len += strlen(src[i]);
  185. }
  186. return len;
  187. }
  188.  
  189. char *stringOutOfArray(char **src, int numColumns) //Од низа од стрингови прави еден стринг одделен со сепаратор, запирка
  190. {
  191. int len = calcLen(src, numColumns) + numColumns-1;
  192. char *temp = new char[len+1];
  193. strcpy(temp, "\0");
  194. for (int i = 0; i < numColumns; i++)
  195. {
  196. strcat(temp, src[i]);
  197. if (i < numColumns - 1)
  198. {
  199. strcat(temp, ",");
  200. }
  201. }
  202. temp[len] = '\0';
  203. return temp;
  204. }
  205.  
  206. void insertCategory(int index, const char *colname)
  207. {
  208. int numRows = countRows(reportFileName);
  209. char **lines = new char*[numRows];
  210. FILE *f = fopen(reportFileName, "r+");
  211. char buff[MAXCOLS];
  212. //
  213. char *line = fgets(buff, MAXCOLS, f);
  214. char numColumns = countColumns(line, ',');
  215. if (index > numColumns)
  216. {
  217. printf("You entered an index which does not fit in this table. Please try again!!!\n");
  218. return;
  219. }
  220. char **splited = words(line, ',', numColumns);
  221. lines[0] = stringOutOfArray(insertInto(splited, colname, index, numColumns), numColumns+1);
  222. //
  223. int i = 1;
  224. while ((line = fgets(buff, MAXCOLS, f)) != NULL)
  225. {
  226. splited = words(line, ',', numColumns);
  227. lines[i] = stringOutOfArray(insertInto(splited, "0", index, numColumns), numColumns+1);
  228. }
  229. fclose(f);
  230. //
  231. f = fopen(reportFileName, "w");
  232. for (int i = 0; i < numRows; i++)
  233. {
  234. fprintf(f, "%s", lines[i]);
  235. }
  236. fclose(f);
  237. //
  238. }
  239.  
  240. int getIndexForName(char **words, int numColumns, const char *name)
  241. {
  242. for (int i = 0; i < numColumns; i++)
  243. {
  244. if (!strcmp(words[i], name))
  245. {
  246. return i;
  247. }
  248. }
  249. return -1;
  250. }
  251.  
  252. int getIndexForName(Category **categories, int numColumns, const char *name)
  253. {
  254. for (int i = 0; i < numColumns; i++)
  255. {
  256. if (!strcmp(categories[i]->name, name))
  257. {
  258.  
  259. return i;
  260. }
  261. }
  262. return -1;
  263. }
  264.  
  265. char **removeFrom(char **src, int index, int numColumns)
  266. {
  267. char **dest = new char*[numColumns - 1];
  268. for (int i = 0; i < index; i++)
  269. {
  270. dest[i] = new char[strlen(src[i])];
  271. strcpy(dest[i], src[i]);
  272. }
  273. for (int i = index; i < numColumns - 1; i++)
  274. {
  275. dest[i] = new char[strlen(src[i + 1])];
  276. strcpy(dest[i], src[i + 1]);
  277. }
  278. return dest;
  279. }
  280.  
  281. void removeCategory(const char *name)
  282. {
  283. int numRows = countRows(reportFileName);
  284. char **lines = new char*[numRows];
  285. FILE *f = fopen(reportFileName, "r+");
  286. char buff[MAXCOLS];
  287. //
  288. char *line = fgets(buff, MAXCOLS, f);
  289. char numColumns = countColumns(line, ',');
  290. char **splited = words(line, ',', numColumns);
  291. int indexOfOccurence = getIndexForName(splited, numColumns, name);
  292. if (indexOfOccurence == -1)
  293. {
  294. printf("There's no such column with the given name. Please try again!!!\n");
  295. return;
  296. }
  297. lines[0] = stringOutOfArray(removeFrom(splited, indexOfOccurence, numColumns), numColumns-1);
  298. //
  299. int i = 1;
  300. while ((line = fgets(buff, MAXCOLS, f)) != NULL)
  301. {
  302. splited = words(line, ',', numColumns);
  303. lines[i] = stringOutOfArray(removeFrom(splited, indexOfOccurence, numColumns), numColumns - 1);
  304. }
  305. fclose(f);
  306. //
  307. f = fopen(reportFileName, "w");
  308. for (int i = 0; i < numRows; i++)
  309. {
  310. fprintf(f, "%s", lines[i]);
  311. }
  312. fclose(f);
  313. //
  314. }
  315.  
  316. void printTable(Category **categories)
  317. {
  318. for (int i = 0; i < reportColumns; i++)
  319. {
  320. printf("%-20s", categories[i]->name);
  321. }
  322. printf("\n");
  323. for (int i = 0; i < reportRows - 1; i++)
  324. {
  325. for (int j = 0; j < reportColumns; j++)
  326. {
  327. printf("%-20s", categories[j]->values[i]);
  328. }
  329. printf("\n");
  330. }
  331. }
  332.  
  333. char *constructLineFromExpected(int firstIndex, int secondIndex, int eCost, tm *local, int numColumns) //konstruiram string od vnesena ocekuvana potrosuvacka i datum
  334. {
  335. char *result = new char[MAXCOLS];
  336. strcpy(result, "\0");
  337. for (int j = 0; j < firstIndex; j++)
  338. {
  339. strcat(result, "0,");
  340. }
  341. char buff[32];
  342. strcat(result, strcat(_itoa(eCost, buff, 10), ","));
  343. for (int j = firstIndex + 1; j < secondIndex; j++)
  344. {
  345. strcat(result, "0,");
  346. }
  347. _itoa(local->tm_mday, buff, 10); //denot
  348. strcat(buff, ".");
  349. strcat(result, buff);
  350. _itoa(local->tm_mon + 1, buff, 10); //mesecot
  351. strcat(buff, ".");
  352. strcat(result, buff);
  353. _itoa(START_YEAR + local->tm_year, buff, 10); //godinata (START_YEAR+) bidejki strukturata broi od 1900-tata
  354. strcat(buff, ",");
  355. strcat(result, buff);
  356. for (int j = secondIndex + 1; j < numColumns; j++)
  357. {
  358. strcat(result, "0,");
  359. }
  360. result[strlen(result) - 1] = '\0';
  361. return result;
  362. }
  363.  
  364. int countStrings(char **s) //brojam kolku stringovi ima vo niza od stringovi
  365. {
  366. int count = 0;
  367. while (*s != "\0")
  368. {
  369. count++;
  370. s++;
  371. }
  372. return count;
  373. }
  374.  
  375. int main()
  376. {
  377. struct Category **categories = initializeCategory();
  378.  
  379. const char *naUp = "*********************", *na = "* NatashaAccounting *", *naDown = "*********************";
  380. printf("%50s\n", naUp);
  381. printf("%50s\n", na);
  382. printf("%50s\n", naDown);
  383.  
  384. printf("\n\n\nWELCOME!\n");
  385. time_t curtime;
  386.  
  387. int choice;
  388. while (1)
  389. {
  390. printf("\n1) Print the montly report (categories) table\n");
  391. printf("2) Insert a category\n");
  392. printf("3) Remove a category\n");
  393. printf("4) Change/Insert expected cost for the current/next month\n");
  394. printf("5) Insert an item\n");
  395. printf("6) EXIT\n");
  396.  
  397. scanf("%d", &choice);
  398. if (choice == 1)
  399. {
  400. printTable(categories);
  401. }
  402. if (choice == 2)
  403. {
  404. int colIndex;
  405. char colName[50];
  406. printf("Enter the position on the new column (starting from 0): ");
  407. scanf("%d", &colIndex);
  408. printf("Enter a name for the new column (without blank space): ");
  409. scanf("%s", colName);
  410. insertCategory(colIndex, colName);
  411. categories = initializeCategory();
  412. getchar();
  413. char ans;
  414. printf("Would you like to create a new table for the given category?(Y/N): ");
  415. scanf("%c", &ans);
  416. if (ans == 'Y' || ans == 'y')
  417. {
  418. FILE *f = fopen(strcat(colName, ".csv"), "w");
  419. char s[] = "Name,Quantity,Price,Date\0";
  420. fwrite(s, 1, sizeof(s), f);
  421. fclose(f);
  422. }
  423.  
  424. }
  425. if (choice == 3)
  426. {
  427. char colName[50];
  428. printf("Enter the name of the column which you want to be removed: ");
  429. scanf("%s", colName);
  430. removeCategory(colName);
  431. categories = initializeCategory();
  432. remove(strcat(colName, ".csv"));
  433. }
  434. if (choice == 4)
  435. {
  436. int eCost; //novata ocekuvana potrosuvacka
  437. printf("Vnesete go iznosot (vo denari) sto ocekuvate deka ke go potrosite: ");
  438. scanf("%d", &eCost);
  439. FILE *f = fopen(reportFileName, "r");
  440. char buff[MAXCOLS];
  441. char *line;
  442. int i;
  443. char **toBeWritten = new char*[reportRows + 2]; //noviot raspored na katerogii so dodadeni/izmeneti vrednosti
  444. for (i=0; i<reportRows; i++) //kopiranje na se sto e vo datotekata vo toBeWritten
  445. {
  446. line = fgets(buff, MAXCOLS, f);
  447. toBeWritten[i] = new char[strlen(line)+1];
  448. strcpy(toBeWritten[i], line);
  449. toBeWritten[i][strlen(line)] = '\0';
  450. }
  451. time(&curtime); //zemanje na tekovnoto vreme vo sekundi
  452. tm *local = localtime(&curtime); //gradenje struktura od koja ke gi izvlecam denot, mesecot i godinata
  453. int indexDate = getIndexForName(categories, reportColumns, "Date"); //baram na koj indeks e datata
  454. char *result = "\0"; //rezultantniot string so vnesenata expected potrosuvacka
  455.  
  456. if (reportRows - 1 > 0 ) //dokolku veke ima vneseno potrosuvacka
  457. {
  458. char **catDate = words(categories[indexDate]->values[i - 2], '.', DATE_COLUMNS); //gi izdvojuvam denot mesecot i godinata od datumot
  459. int indexExpected = getIndexForName(categories, reportColumns, "Expected_cost"); //pronajdi ja kolonata Expected_Cost
  460.  
  461. if (indexExpected < indexDate) //konstruiram string zavisno od redosledot
  462. {
  463. result = constructLineFromExpected(indexExpected, indexDate, eCost, local, reportColumns);
  464. }
  465. else {
  466. result = constructLineFromExpected(indexDate, indexExpected, eCost, local, reportColumns);
  467. }
  468.  
  469. if (atoi(catDate[2]) == START_YEAR + local->tm_year && atoi(catDate[1]) == local->tm_mon + 1) //dokolku se poklopuvaat, azuriraj
  470. {
  471. toBeWritten[i - 1] = new char[strlen(result) + 1];
  472. strcpy(toBeWritten[i - 1], result);
  473. toBeWritten[i - 1][strlen(result)] = '\0';
  474. toBeWritten[i] = "\0";
  475. }
  476. else //vo sprotivno dodadi nova smetka za noviot mesec
  477. {
  478. toBeWritten[i] = new char[strlen(result) + 1];
  479. strcpy(toBeWritten[i], result);
  480. toBeWritten[i][strlen(result)] = '\0';
  481. toBeWritten[i + 1] = "\0";
  482. }
  483. }
  484. else //vo sprotivno odnesuvaj se kako da treba da dodades nova smetka
  485. {
  486. int indexExpected = getIndexForName(categories, reportColumns, "Expected_cost");
  487. if (indexExpected < indexDate)
  488. {
  489. result = constructLineFromExpected(indexExpected, indexDate, eCost, local, reportColumns);
  490. }
  491. else {
  492. result = constructLineFromExpected(indexDate, indexExpected, eCost, local, reportColumns);
  493. }
  494. toBeWritten[i] = new char[strlen(result) + 1];
  495. strcpy(toBeWritten[i], result);
  496. toBeWritten[i][strlen(result)] = '\0';
  497. toBeWritten[i + 1] = "\0";
  498. }
  499. fclose(f);
  500. f = fopen(reportFileName, "w+");
  501. for (int j = 0; j < i + 1; j++) //gi stavam azuriranite/dodadenite smetki vo istata tabela
  502. {
  503. fprintf(f, "%s\n", toBeWritten[j]);
  504. }
  505. fclose(f);
  506. categories = initializeCategory();
  507. }
  508. if (choice == 5)
  509. {
  510. int catId;
  511. printf("Please select a category:\n");
  512. for (int i = 0; i < reportColumns; i++)
  513. {
  514. printf("%d) %s\n", i + 1, categories[i]->name);
  515. }
  516. scanf("%d", &catId);
  517. if (catId <= reportColumns) //dokolku e vnesen validen indeks
  518. {
  519. if (categories[catId - 1]->isCategory == 1) //dokolku kategorijata ima tabela
  520. {
  521. char cName[50], cQuantity[32], cPrice[32], cDate[12];
  522. printf("Ime na produktot (praznoto mesto zameneto go so dolna crta)? ");
  523. scanf("%s", cName);
  524. printf("Kolicina? ");
  525. scanf("%s", cQuantity);
  526. printf("Cena? ");
  527. scanf("%s", cPrice);
  528. printf("Data na kupuvanje (d.m.yyyy)? ");
  529. scanf("%s", cDate);
  530. char itemRow[MAXCOLS];
  531. strcpy(itemRow, "\n");
  532. strcat(itemRow, cName);
  533. strcat(itemRow, ",");
  534. strcat(itemRow, cQuantity);
  535. strcat(itemRow, ",");
  536. strcat(itemRow, cPrice);
  537. strcat(itemRow, ",");
  538. strcat(itemRow, cDate);
  539. itemRow[strlen(itemRow)] = '\0';
  540. char *tempName = new char[strlen(categories[catId - 1]->name)+1];
  541. strcpy(tempName, categories[catId - 1]->name);
  542. tempName[strlen(tempName)] = '\0';
  543. FILE *tempF = fopen(strcat(tempName, ".csv"), "a");
  544. fprintf(tempF, itemRow);
  545. fclose(tempF);
  546. initializeItems(categories[catId - 1]);
  547. }
  548. else
  549. {
  550. printf("Izbranata kategorija na sodrzi tabela so produkti. Ve molime izberete soodvetna katerogija!");
  551. }
  552. }
  553. else
  554. {
  555. printf("Vnesovte nevalidna opcija!!! Obidete se povtorno.\n");
  556. }
  557. }
  558. if (choice == 6)
  559. {
  560. break;
  561. }
  562. }
  563. system("PAUSE");
  564. return 0;
  565. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement