JBTALKS.CC

标题: string calculator [打印本页]

作者: yangss    时间: 2010-8-25 09:46 PM
标题: string calculator
我在弄一个利用string input的calculator~程序需要加减乘除还有普通的calculator用法~我大概是知道把所有的string放进temp里面~然后丢进function来做数学~得到了先乘除的value~然后在丢回temp~继续做其他的~例如~我的input时123+456*789~我必须先把全部放进temp~然后进入function做乘除~过后做了456*789的答案~就是说把359784放进temp~temp现在应该就是123+359784~然后又再loop过~做到完整答案为止~这是我agak agak写的程序~
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
void main()
{
char x[100];
char operant[10];
char nx[100];
char temp[100];
int n, i=0, j=0;
printf("?");
gets(x);
n=strlen(x);
for(i=0;i<n;i++)
{
nx[i]=x[i];
strncpy(temp,&x[i],1);
printf("%s",temp);
}
getchar();
}
void operant()
{
do
{
while(x[i]!='+' || x[i]!='-')
{
if(x[i]=='*')
nx[i-1]*nx[i+1];
else if(x[i]=='/')
nx[i-1]/nx[i+1];
}
}
while(x[i]!='+' || x[i]!='-')
{
if(x[i]=='+')
nx[i-1]+nx[i+1];
else if(x[i]=='-')
nx[i-1]-nx[i+1];
}
我真的不知道怎样拿跟存value~更不懂该怎样写下去~这是我的assignment~希望你们可以帮帮忙~
作者: 宅男-兜着走    时间: 2010-8-26 01:38 AM
我在弄一个利用string input的calculator~程序需要加减乘除还有普通的calculator用法~我大概是知道把所有的 ...
yangss 发表于 2010-8-25 09:46 PM



    好像没看到 Parse 这个动作。
作者: yangss    时间: 2010-8-26 01:44 AM
parse我完全不理解~我学c language不到三个月~初学者~paiseh paiseh~ ~可以教教我用吗?之前有人教我用atoi atof~这我也不认识它~那个会比较适合?请教教小弟~点条明路~
作者: 慾哭無淚    时间: 2010-8-26 04:43 AM
atoi 和  atof 是 c 的 function

atoi 是用来 string convert 去 integer
atof 是用来 string convert 去 double

www.cplusplus.com/reference/clibrary/cstdlib/atof/
作者: Super-Tomato    时间: 2010-8-26 06:25 AM
本帖最后由 Super-Tomato 于 2010-8-26 06:28 AM 编辑
我在弄一个利用string input的calculator~程序需要加减乘除还有普通的calculator用法~我大概是知道把所有的string放进temp里面~然后丢进 function来做数学~得到了先乘除的value~然后在丢回temp~继续做其他的~例如~我的input时123+456*789~我必须先把全部放进temp~然后进入function做乘除~过后做了456*789的答案~就是说把359784放进temp~temp现在应该就是 123+359784~然后又再loop过~做到完整答案为止~这是我agak agak写的程序~
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<math.h>
  5. void main()
  6. {
  7. char x[100];
  8. char operant[10];
  9. char nx[100];
  10. char temp[100];
  11. int n, i=0, j=0;
  12. printf("?");
  13. gets(x);
  14. n=strlen(x);
  15. for(i=0;i<n;i++)
  16. {
  17. nx[i]=x[i];
  18. strncpy(temp,x[i],1);
  19. printf("%s",temp);
  20. }
  21. getchar();
  22. }
  23. void operant()
  24. {
  25. do
  26. {
  27. while(x[i]!='+' || x[i]!='-')
  28. {
  29. if(x[i]=='*')
  30. nx[i-1]*nx[i+1];
  31. else if(x[i]=='/')
  32. nx[i-1]/nx[i+1];
  33. }
  34. }
  35. while(x[i]!='+' || x[i]!='-')
  36. {
  37. if(x[i]=='+')
  38. nx[i-1]+nx[i+1];
  39. else if(x[i]=='-')
  40. nx[i-1]-nx[i+1];
  41. }
复制代码
我真的不知道怎样拿跟存value~更不懂该怎样写下去~这是我的assignment~希望你们可以帮帮忙~
yangss 发表于 2010-8-25 09:46 PM


想法大致上是這样,但是你的 coding 幾乎很亂,而且没仔细去了解函数的用法

1. strncpy(temp,x[i ],1);
不明白你一直复写這個干嘛,而且没搞清楚 strncpy 的第二参數作用,如果只是要复制字元(char)直接 temp[ i] = x[ i] 就好了

2. getchar();
之前都已經使用 gets 了,那麽你還用 getchar 函数做甚么??

3. void operant()
不知是复制過來的問題還是論壇的所見所得功能問題,怎么你自定义的函数會在 main 中?

4. do... while 用法錯誤,請翻查一下你的教學課本或小抄

5. 所有的数学运算部份都没有做變數儲存,這样的寫法是錯誤的




最後看了你的 while 部份發現你所编写的和你一開始說明的逻辑有出入
if(x[i ] == '*')
            nx[i-1]*nx[i+1];

你目前做的只能够把個位數做加减,一個 char 就只能存一個字元,所以 23 不等于 2,3
作者: yangss    时间: 2010-8-26 11:58 AM
那就是说strncpy用不着?用temp[i]=x[i]把各char储存就可以?我怎么没想到~现在temp[i]已经储存所有string~可是我还是不会把它们归类成正正的数字~就好像123+456~各temp[i]储存了每个char~但它们始终都是一个个的单数字~temp[0]=1,temp[1]=2,temp[2]=3等等~我要怎样把它们归类回变成123整数这样?我也知道我的数学运算部份都没有做變數儲存~但如果我没能把它们归类成数字的话~我就写不出~问题就这样~不懂得把它们弄成actual value~运算部分就卡住了~我也很清楚目前做的只能够把個位數做加减~就像123+456变成了3+4罢了~对不对?
作者: Super-Tomato    时间: 2010-8-26 03:27 PM
那就是说strncpy用不着?用temp[i ]=x[i ]把各char储存就可以?我怎么没想到~现在temp[i ]已经储存所有string~可是我还是不会把它们归类成正正的数字~就好像123+456~各temp[i ]储存了每个char~但它们始终都是一个个的单数字~temp[0]=1,temp[1]=2,temp[2]=3等等~我要怎样把它们归类回变成123整数这样?我也知道我的数学运算部份都没有做變數儲存~但如果我没能把它们归类成数字的话~我就写不出~问题就这样~不懂得把它们弄成actual value~运算部分就卡住了~我也很清楚目前做的只能够把個位數做加减~就像123+456变成了3+4罢了~对不对?
yangss 发表于 2010-8-26 11:58 AM


所以以你目前的方式來做的話,首先要循环的是在判断遇到數學符号的時候才使用 strncpy 把幾個数字的字元儲存为一個字串(string)

char * strncpy ( char * destination, const char * source, size_t num );

Copy characters from stringCopies the first num characters of source to destination. If the end of the source C string (which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.

No null-character is implicitly appended to the end of destination, so destination will only be null-terminated if the length of the C string in source is less than num.

ParametersdestinationPointer to the destination array where the content is to be copied.sourceC string to be copied.numMaximum number of characters to be copied from source.

Return Valuedestination is returned.
   

大多在网上找到都是做個基本從第一個字開始复制的范例,而你仔细去阅读参數的 “型态” 就無法运用,以下這個例子自己去測試後學習以後怎么去了解各函数所提供的参數運用


  1. #include<stdio.h>
  2. #include<string.h>

  3. int main ()
  4. {
  5.   char s[17] = "This is a string.";
  6.   char d[8] = "";

  7.   strncpy(d, s, 7);
  8.   printf("strncpy from char 0 to 7 will get value : (%s)\n", d);

  9.   strncpy(d, s + 10, 7);
  10.   printf("strncpy from char 10 to end will get : (%s)\n\n", d);

  11.   return 0;
  12. }
复制代码

作者: yangss    时间: 2010-8-26 11:57 PM
我已经改良了我的code~已经可以把所有的数目还有加减乘除sign~各都进入了array~我想问问如果我要拿加减乘除sign前后的数目来做数学~我应该怎样做?
作者: Super-Tomato    时间: 2010-8-27 12:19 AM
本帖最后由 Super-Tomato 于 2010-8-27 12:22 AM 编辑
我已经改良了我的code~已经可以把所有的数目还有加减乘除sign~各都进入了array~我想问问如果我要拿加减乘除 ...
yangss 发表于 2010-8-26 11:57 PM



既然你都已經分别存入陣列中了,那麽只要依照之前循环搜索即可取得運算符号
但 C 的陣列没函数套用做新增/修改或删除,所以你就必須自己编写以方便自己


要不你就使用看看 struct 配合 linked-list 對你來說會不會简单些
作者: yangss    时间: 2010-8-27 12:33 AM
又再更新了~已经可以做加减乘除~但问题就是加减混乘除一起做就会有问题~例如~5+5*5+5应该得到35~可是我的答案是30~我觉得index出了问题~我把sign跟数目的index分开~可是它会loop不完~我写在纸草稿~发现index会有空的value~
作者: Super-Tomato    时间: 2010-8-27 12:46 AM
又再更新了~已经可以做加减乘除~但问题就是加减混乘除一起做就会有问题~例如~5+5*5+5应该得到35~可是我的答 ...
yangss 发表于 2010-8-27 12:33 AM



你應該是删了最後的 index 所以就没加上 5

用你目前的測試看看 1+2*5+4/2-2-1 會是多少,11??
作者: yangss    时间: 2010-8-27 12:52 AM
答案是 -1...
作者: yangss    时间: 2010-8-27 01:01 AM
int main()
{
        char txt[200];
        char temp[200][200];
        char opt[200];
        float num[200];
        int i=0, j=0, k=0, n=0, m=0;
       
        printf("?\n");
        gets(txt);
       
        i = strlen(txt);
for(j=0;j<i;j++)
        {
                if(!(txt[j]=='+' || txt[j]=='-' || txt[j]=='*' || txt[j]=='/'))
                {
                         temp[m][k] = txt[j]; k++;
                }
                else
                {                       
            opt[n] = txt[j]; n++;
                        num[m] = atof(temp[m]); m++;
                        k=0;
                                   
                }
        }
        num[m] = atof(temp[m]); m++;
int yee = 0; float ans = 0;
       
        int asd = 0;
       
        asd = strlen(opt);
       
        for(j=0;j<asd;j++)
        {
                if(opt[j]=='*')
                {
                        num[j+1] = num[j] * num[j+1];
                        num[j] = num[j+1];
            ans = num[j+1];                        
                }
                if(opt[j]=='/')
                {
                        num[j+1] = num[j] / num[j+1];
                        num[j] = num[j+1];
            ans = num[j+1];                        
                }
        }
for(j=0;j<asd;j++)
        {
                if(opt[j]=='+')
                {
            num[j+1] = num[j] + num[j+1];
                        num[j] = num[j+1];
            ans = num[j+1];
                                   
                }
                if(opt[j]=='-')
                {
                        num[j+1] = num[j] - num[j+1];
                        num[j] = num[j+1];
            ans = num[j+1];                                
                }
        }
       
   
           
       
        printf("%f",ans);
       
        getchar();
我的程序
作者: Super-Tomato    时间: 2010-8-27 03:01 AM
int main()
{
        char txt[200];
        char temp[200][200];
        char opt[200];
        float num[200];
        int i=0,  ...
yangss 发表于 2010-8-27 01:01 AM



下次把你的 coding 标记起来,不然這样很难看
你的問題主要是在後面運算的時候出現, 假设我要驗算 1+2*3+4 的話

首先你是把数字全記錄在 num 變數中,所以會是
num = 1       2       3       4

之後先搜索到 * 就進行 num[1] 和 num[2] 的乘而使陣列變成
num = 1       6       6       4

再來是 + 而開始對位置 num[0] 和 num[1] 做加法後得陣列
num = 7       7       6       4

最後步驟是做 num[2] + num[3], 所以你可以從上一步看到你的問題點
7       7       10      10


這就是我說的 C 陣列必須做修改和删除不必要的原因
作者: yangss    时间: 2010-8-27 03:12 AM
对了对了~就是这个问题~我在纸上草稿算也是这样~哪有办法可以删除已做了答案的index删除?或者是把数目移前或移后进入其它index?还是要改statement?还有什么办法?
作者: Super-Tomato    时间: 2010-8-27 08:22 AM
对了对了~就是这个问题~我在纸上草稿算也是这样~哪有办法可以删除已做了答案的index删除?或者是把数目移前或移后进入其它index?还是要改statement?还有什么办法?
yangss 发表于 2010-8-27 03:12 AM



所以我才說要自己寫函数删除啊,其实方法就只是把後面的陣列往前 assign 就行,如下:


num = {1, 2, 3, 4}
opt = "+*+"

num = {1, 6, 4}
opt = "++"

num = {7, 4}
opt = "+"


num的长度由 m 控制,所以每次往前 assign 的時候要記得把 m 减少
作者: yangss    时间: 2010-8-30 10:33 PM
这个函数我应该怎样开始?指点指点~
作者: Super-Tomato    时间: 2010-8-31 12:39 AM
这个函数我应该怎样开始?指点指点~
yangss 发表于 2010-8-30 10:33 PM



這里你自己都應用過了啊,怎么不变通呢??
        for(j=0;j<asd;j++)
        {
                if(opt[j]=='*')
                {
                        num[j+1] = num[j] * num[j+1];
                        num[j] = num[j+1];
            ans = num[j+1];                        
                }
                if(opt[j]=='/')
                {
                        num[j+1] = num[j] / num[j+1];
                        num[j] = num[j+1];
            ans = num[j+1];                        
                }
        }


以你目前的编写情况來看,不嫌麻烦的话就是不用函数,但需要在每個運算符号中寫一次
而要轻松點的方式就是使用函数把 num 和 opt 中多餘不必要的陣列删掉,當然是用 pointer 方式可以简化很多步驟
作者: yangss    时间: 2010-9-1 12:49 AM
那我是不是要用pointer来指定那个index应该用,那个index不应该用?
作者: Super-Tomato    时间: 2010-9-1 08:02 AM
那我是不是要用pointer来指定那个index应该用,那个index不应该用?
yangss 发表于 2010-9-1 12:49 AM



你對 pointer 没甚么概念,所以還是不要用的好,一知半解最危险
現在你自己草稿在纸上,看看你的陣列要怎么改变,要删除哪一個和删除之後會是形成怎样的結果
作者: yangss    时间: 2010-9-1 07:45 PM
已经改了我的程序~加减乘除没大碍了~现在要做parentheses solver~也就是说挂号~我应该先做挂号里面的东西~才可以继续做以外的~可是不懂怎样~我应该怎样做?指点指点~
作者: Super-Tomato    时间: 2010-9-2 06:54 AM
已经改了我的程序~加减乘除没大碍了~现在要做parentheses solver~也就是说挂号~我应该先做挂号里面的东西~才可以继续做以外的~可是不懂怎样~我应该怎样做?指点指点~
yangss 发表于 2010-9-1 07:45 PM


其实都是同理做法, 你現在是循环先搜索 opt 中的 * / + -, 同样的方式先搜索最后一個 ( 之後再找出接下來的第一個 )
都找到了就做之間的加减乘除運算,但以你目前的编写方式来看應該會寫到很亂,所以建议你還是去掌握一下 function 的用法
作者: yangss    时间: 2010-9-2 07:36 AM
回复 22# Super-Tomato


    如果用function来做,那又会是怎样?如果用一样的做法就是跟之前的加减乘除同样道理,再加上挂号但我要怎样跟它说先做挂号里的东西?这个似乎一定要用function来做。
作者: Super-Tomato    时间: 2010-9-2 06:06 PM
回复  Super-Tomato


    如果用function来做,那又会是怎样?如果用一样的做法就是跟之前的加减乘除同 ...
yangss 发表于 2010-9-2 07:36 AM



你現在欠缺是思考,先去了解 function 的用法之後,再回顾你所输入的文字要怎么使用循环搜索出 ( 和 )
最後想想你一開始的逻辑和需要定义出哪些 function
作者: yangss    时间: 2010-9-2 07:47 PM
我的老师叫我用strncpy的方法,例如1+(2+3)*4-5,把(2+3)copy出来~然后做算草~得到答案了把答案丢回进去~这个方法是不是就不用用function了?
作者: Super-Tomato    时间: 2010-9-2 08:53 PM
我的老师叫我用strncpy的方法,例如1+(2+3)*4-5,把(2+3)copy出来~然后做算草~得到答案了把答案丢回进去~这个 ...
yangss 发表于 2010-9-2 07:47 PM



這样是叫你拆字串和接字串,使用的陣列就没有那麽复杂麻烦,但一样需要使用循环一直判断到没有操作符号
程式中不使用 function 當然是没有問題,只要你自己思维逻辑清晰的话随你喜欢怎么用。
不過以你目前來看,幾乎所有基础都才刚開始就想把所有的東西都简化,應該有苦能讓你慢慢吃了。
作者: yangss    时间: 2010-9-2 10:08 PM
回复 26# Super-Tomato


    那麻烦你先教教我用strncpy吧那(2*3)copy出来~
作者: Super-Tomato    时间: 2010-9-2 10:57 PM
回复  Super-Tomato


    那麻烦你先教教我用strncpy吧那(2*3)copy出来~
yangss 发表于 2010-9-2 10:08 PM



既然是文字,當然就该使用文字搜索,从字串中找到最後一個 ( 的"位置"即該字串陣列中的 index, 然後再往下找第一個遇到的 )
如此有了两個 index 數字當然就可以知道要复制多長的字串和從哪開始复制


字串 A = 字串1(字串2)字串3

字串 B = 字串1
字串 C = 字串2 去前後 ( ) 後套用目前 + - * / 的方式可得到
字串 D = 字串3

字串 A = 字串 B + 字串 C + 字串 D
繼續循环



strncpy 的例子我已經回過了,所以你就自己去研究,還有发掘我所没寫出的特性
接下去你提出問題的同时先把你所思考的逻辑或概念先寫出來, 不然這就是我在动脑做功课而不是你
作者: yangss    时间: 2010-9-2 11:03 PM
回复 28# Super-Tomato


    我要昏了~~O(∩_∩)O哈哈~谢谢这么久以来的指点~我自己再慢慢参考下~




欢迎光临 JBTALKS.CC (https://jbtalks.my/) Powered by Discuz! X2.5