mbah_bejo

dokumentasi

Dec 9th, 2021
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.84 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h> // untuk strlen(), memmove(), strstr(), strncpy
  3. #include <math.h> //untuk pow()
  4. #include <ctype.h> // untuk isspace, isdigit
  5. #include <stdlib.h> // untuk system("clear")
  6.  
  7. void home()
  8. {
  9. printf("\n \n");
  10. printf("=================================================================== \n");
  11. printf("KALKULATOR MINI\n");
  12. printf("<-->\n");
  13. printf("Operator yang diperbolehkan: + - * / ()\n");
  14. printf("Special Commands: cls[Clear Screen], x[Stop Program]\n");
  15. printf("<-->\n");
  16. printf("=================================================================== \n");
  17. printf("\n \n");
  18. }
  19.  
  20. // Function to replace a string with another
  21. // string
  22. char* replace(char* source, size_t sourceSize, char* substring, char* with) {
  23. char* substring_source = strstr(source, substring);
  24. if (substring_source == NULL) {
  25. return NULL;
  26. }
  27.  
  28. if (sourceSize < strlen(source) + (strlen(with) - strlen(substring)) + 1) {
  29. printf("Buffer size is too small\n");
  30. return NULL;
  31. }
  32.  
  33. memmove(
  34. substring_source + strlen(with),
  35. substring_source + strlen(substring),
  36. strlen(substring_source) - strlen(substring) + 1
  37. );
  38.  
  39. memcpy(substring_source, with, strlen(with));
  40. return substring_source + strlen(with);
  41. }
  42.  
  43. // Following function extracts characters present in `src`
  44. // between `m` and `n` (excluding `n`)
  45. char* substr(const char *src, int m, int n)
  46. {
  47. // get the length of the destination string
  48. int len = n - m;
  49.  
  50. // allocate (len + 1) chars for destination (+1 for extra null character)
  51. char *dest = (char*)malloc(sizeof(char) * (len + 1));
  52.  
  53. // start with m'th char and copy `len` chars into the destination
  54. strncpy(dest, (src + m), len);
  55.  
  56. // return the destination string
  57. return dest;
  58. }
  59.  
  60. void hilangSpasi(char * input){
  61. //menghitung panjang string
  62. int len = strlen(input);
  63. // printf("%d", len);
  64. //Checks for space character in array if its there then ignores it and swap str[i] to str[i+1];
  65. for(int i = 0; i < len; i++){
  66. if(isspace(input[i])){
  67. for(int j=i;j<len;j++)
  68. {
  69. input[j]=input[j+1];
  70. }
  71. len--;
  72. }
  73. }
  74. // printf("%s", input);
  75. }
  76.  
  77. char * Hitung(char * input){
  78.  
  79. int j=0;
  80. int len = strlen(input);
  81. // printf("len = %d\n", len);
  82.  
  83. for(int i = 0 ; i< len; ++i){
  84. //cek setiap char, apakah ada yg bukan angka/operator
  85. if(!isdigit(input[i]) && !ispunct(input[i])) break;
  86. // printf("lewat break");
  87. // mulai kalkulasi saat sudah char terakhir
  88. if(i == len - 1){
  89. for (int i = 0; i < len; ++i)
  90. {
  91. //cek kalau ada tanda kurung ()
  92. if(input[i] == '('){
  93. j = i;
  94. for (int i = 1; i > 0; --i){
  95. while (input[j]!=')')
  96. {
  97. ++j;
  98. if(input[j]=='(') ++i;
  99. }
  100. //kalau tanda '(' ada ditengah-tengah
  101. //posisi j ditambah 1 untuk penyesuaian
  102. if(i > 1) ++j;
  103. }
  104. //ambil substring dari string, di posisi i+1, dengen panjang j - i - 1
  105. char* temp_substr = substr(input, i + 1, j);
  106. // hitung hasil substring
  107. Hitung(temp_substr);
  108. // ambil bagian yang akan ditukar dengan substring
  109. char* temp_to_change = substr(input, i, j+1);
  110. // melakukan replace dari operasi() dengan substring hasil
  111. replace(input, len, temp_to_change, temp_substr);
  112. }
  113. }
  114.  
  115. //mulai perhitungan
  116. //step 1 untuk perkalian & pembagian
  117. //step 2 untuk penjumlahan & pembagian
  118. for(int step =1 ; step<=2; ++step){
  119. // printf("step = %d\n", step);
  120. // printf("input = %s\n", input);
  121.  
  122. //jadi penanda operator
  123. char x, y;
  124.  
  125. if (step == 1)
  126.  
  127. x = '*', y = '/';
  128. else
  129. x = '+', y = '-';
  130.  
  131. //mulai memeriksa setiap isi input
  132. for (int i = 0; i < strlen(input); ){
  133. // printf("len dalam step = %d\n", strlen(input));
  134. // printf("input[%d] = %c\n",i, input[i]);
  135.  
  136. //jika ada input[i] yang menjadi operator
  137. if (input[i] == x || input[i] == y){
  138. //masuk operasi
  139. // printf("input[%d] = %c\n",i, input[i]);
  140. long double leftOp = 0, rightOp = 0;
  141. int rightIterator = i, s = i;
  142. short sign = 1;
  143. int flag = 0;
  144.  
  145. // mulai iterasi untuk mencari bilangan sebelum operator/input[i-1]
  146. for (int k = 0; i > 0 && (isdigit(input[i - 1]) || input[i - 1] == '-' || input[i - 1] == '.'); ++k){
  147. flag = 1;
  148.  
  149. // printf("k: %d\nleftOp: %Lf\n", k, leftOp);
  150. // printf("%d - input[i - 1] = %c\ninput[i - 2]: %c\n", i, input[i - 1] , input[i - 2] );
  151.  
  152. if (input[i - 1] == '-'){
  153. if ((i - 2) >= 0 && (input[i - 2] == '*' || input[i - 2] == '+' || input[i - 2] == '-' || input[i - 2] == '/') || i == 1){
  154. leftOp *= -1;
  155. --i;
  156. }
  157. break;
  158. }
  159. // untuk merubah bilangan dibelakang koma yg diperoleh dari leftOp
  160. //bilangan 2.154, maka diproses terlebih dahulu bilangan dibelakang koma
  161. //diperoleh leftOp 154. ini masih bentuk ratusan, maka di rubah dari desimal
  162. //menjadi 0.154 dengan cara 154/10 hingga
  163. else if (input[i - 1] == '.'){
  164. if (leftOp == 0)
  165. {
  166. --i;
  167. continue;
  168. } else {
  169. while ((int)leftOp > 0) leftOp /= 10;
  170. int temp = i;
  171. while (input[temp++] == '0') leftOp /= 10;
  172. k = -1;
  173. }
  174. }else{
  175. // untuk menambahkan bilangan sebelumnya dengan yang sekrang
  176. // misal sudah ada 5, baru ada angka "4", maka "4" dirubah menjadi int
  177. // dan dikali dengan 10^k. k = urutan bilangan(satuan, puluhan, dst)
  178. // (input[i - 1] - 48) untuk konver char menjadi int
  179.  
  180. // printf("input[%d-1] = %d\n",i, input[i-1]-48);
  181. leftOp += (input[i - 1] - 48) * pow(10, k);
  182. }
  183.  
  184. --i;
  185. // printf("%d - leftOp = %Lf\n", k, leftOp );
  186. }
  187.  
  188.  
  189. short floatCounter = 0;
  190. for (rightIterator; rightIterator < strlen(input) && (isdigit(input[rightIterator + 1]) || input[rightIterator + 1] == '-' || input[rightIterator + 1] == '.'); ++rightIterator){
  191. // printf("%d - input[rightIterator-1] = %c\n",rightIterator, input[rightIterator-1]);
  192. if (input[rightIterator + 1] == '-' && (input[rightIterator] == '*' || input[rightIterator] == '+' || input[rightIterator] == '-' || input[rightIterator] == '/'))
  193. sign = -1;//merubah nilai menjadi negatif/sebaliknya. misal ada case seperti 1*-2
  194. else if (input[rightIterator + 1] == '-')
  195. break;
  196. else if (input[rightIterator + 1] == '.')
  197. floatCounter = 1;//penanda adanya bilang desimal disebelah kanan operator
  198. else if (floatCounter == 0)
  199. //jika tidak ada bilangan desimal, maka dapat mementuk nilai dari sebelah kanan operator
  200. //yg kemudian disimpan di rightOp
  201. rightOp = rightOp * 10 + input[rightIterator + 1] - 48;
  202. else
  203. //jika ada bilangan desimal, maka nilai rightOP sebelumnya
  204. //cukup ditambahkan dengan char yg berikutnya
  205. //(input[rightIterator + 1] - 48) * pow(10, -1 * floatCounter++) untuk merubah char menjadi
  206. //bilangan di belakang "."
  207. rightOp += (input[rightIterator + 1] - 48) * pow(10, -1 * floatCounter++);
  208. }
  209.  
  210. rightOp *= sign;
  211.  
  212. // printf("rightOP = %Lf\n", rightOp);
  213. if (flag == 0){
  214. ++i;
  215. continue;
  216. }
  217.  
  218.  
  219. if (step == 2)
  220. //perhitungan untuk penjumlahan dan pengurangan
  221. if(input[s] == '+'){
  222. leftOp += rightOp;
  223. // printf("leftOp+ = %Lf\n", leftOp);
  224. } else leftOp -= rightOp;
  225. else if (input[s] == '*')
  226. //perhitungan untuk perkalian
  227. leftOp *= rightOp;
  228. else if (rightOp != 0)
  229. //perhitungan untuk pembagian
  230. leftOp /= rightOp;
  231. else{
  232. //kalau dibagi 0
  233. puts("Exception! Division by zero.\n");
  234. return input;
  235. }
  236.  
  237.  
  238. //bagian string temp
  239. printf("leftOp = %Lf\n", leftOp);
  240.  
  241. char temp[50]={'\0'};
  242. sprintf(temp, "%Lf", leftOp);//merubah isi leftOP jadi string dan disimpan ke temp
  243.  
  244. // printf("%s - dari temp\n", temp);
  245. //untuk menghilangkan nol pada setelah semua bilangan desimal
  246. if(temp[strlen(temp)-1] == '0'){
  247. printf("%c - isi temp\n", temp[strlen(temp)-1]);
  248. for (int i = strlen(temp) - 1; temp[i] == '0'; i--){
  249. // printf("%c - isi temp[i]\n", temp[i]);
  250. // printf("%c - isi temp[i+1]\n", temp[i+1]);
  251. memmove(&temp[i], &temp[i + 1], strlen(temp) - i);
  252. }
  253. memmove(&temp[i], &temp[i + 1], strlen(temp) - i);
  254.  
  255. if (temp[strlen(temp) - 1] == '.')
  256. memmove(&temp[strlen(temp) - 1], &temp[strlen(temp)], strlen(temp) - i);
  257. }
  258. // printf("rightIterator: = %d\n", rightIterator);
  259.  
  260. char* temp_to_change = substr(input, i, rightIterator+1);
  261. // puts(temp_to_change); printf("- temp_to_change\n");
  262.  
  263. // melakukan replace dari operasi() dengan substring hasil
  264. replace(input, 100, temp_to_change, temp);
  265. // puts(input); printf("- dari input hasil temp\n");
  266.  
  267. }
  268. else ++i;
  269. }
  270. }
  271. return input;
  272. }
  273. }
  274. return "salah Input!";
  275. }
  276.  
  277.  
  278. int main(){
  279. char input[100]={'\0'};
  280. home();
  281. do
  282. {
  283. printf("Masukkan soal matematikamu deh~\n");
  284. printf(">>");
  285. fgets(input, sizeof(input), stdin);
  286. // scanf("%[^\n]s",input);
  287. // printf("%s - input\n", input);
  288. if (strcmp(input, "cls\n") == 0) {
  289. system("clear");
  290. home();
  291. }
  292. if (strcmp(input, "x\n") == 0) break;
  293. hilangSpasi(input);
  294. // printf("%s - input\n", input);
  295. printf("Hasil = %s\n", Hitung(input));
  296. // printf(" - input\n");
  297. } while (1);
  298. return 0;
  299. }
Add Comment
Please, Sign In to add comment