解决 - 其色带作为输入计算的电阻值 [英] SOLVED - Calculating the resistor value with its color bands as input

查看:298
本文介绍了解决 - 其色带作为输入计算的电阻值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图开发一种通过输入标记在电阻上的色带计算电阻值的C程序。

忽略电阻容差。

例如。

 输入电阻器的三个频段的颜色,刚开始
与最近结束了乐队。键入小写字母的颜色
信件只,NO CAPS
波段1 =>绿色
带2 =>黑色
带3 =>黄色
电阻值:500 000 -ohms
你想脱code另一电阻(Y / N)?
= GT; ÿ


  

      
  1. 显示电阻值的要求的格式。例如,如果该电阻值是500000 -ohms,格式需要是
      500 000 -ohms。一个空间有每3位之间被投入。

  2.   
  3. 显示一个无效颜色。例如,如果'褐色','vilet',和'红'被输入作为电阻的色彩,该程序
      生成以下消息:无效的颜色:vilet 这里只
      vilet'是唯一的无效颜色。

  4.   
  5. 显示多个无效颜色。例如,如果粉红,银和红色被输入作为电阻的色彩,该程序
      应该产生在一行下面的消息:
      无效的颜色:粉色,银色这里有两个颜色无效粉红和
      '银'。注意'颜色'。

  6.   

现在我在与获得的格式为总阻力困难的时候(#1)。和#2及#3当且仅当所述第一输入端(带1)是无效的程序将运行。如果第二带或第三带是无效的,而不在第一带是无效的,程序将停止执行。

下面是code,我一直在努力:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&math.h中GT;//电阻带
枚举resistor_band_items {黑,棕,红,橙,黄,绿,蓝,紫,灰,白,未知};项目结构
 {
    字符*名称;
    枚举resistor_band_items ID;
 } item_list [] = {
    {黑,BLACK},
    {棕色,布朗},
    {红,红},
    {橙色,ORANGE},
    {黄,黄色},
    {绿色,绿色},
    {蓝,蓝},
    {紫罗兰,VIOLET},
    {灰色,灰色},
    {白,白}
};焦炭答案[10],状态[1] =Y; //答案=>用户输入
炭频带[3] [10]; //字符串电阻带
//变量来保存乐队值
INT颜色[3];
//函数原型
INT inputVal为(int *一个,炭B〔3] [10]);
双calResistance(INT A,INT B,INT C);
无效print_number(双号);INT主要(无效)
{
    INT I,无效; //计数器
    双resistor_value; //总电阻值
    枚举resistor_band_items中旬;
    结构项目*选择= NULL;    而(的strcmp(状态,Y)== 0)
    {
        //打印问题向用户
        的printf(请输入电阻器的三个频段的颜色,\\与乐队nbeginning最接近最终\\ n类型以小写字母只,缺盖的coloues \\ n。);
        为(中间体J = 0; J&下; 3; J ++)
        {
            的printf(%乐队D =>中,J + 1);
            得到(回答);
            对于(i = 0,选择= NULL; I< sizeof的item_list /的sizeof(结构件); ++ I)
            {
                如果(STRCMP(回答,item_list [我]。名称)== 0)
                {
                    选择= item_list + I;
                    打破;
                }
            }
            中期=选择?选择 - > ID:不详;
            颜色[J] =中;
            的strcpy(带[J],答案);
        }
        无效= inputVal(彩色,带);
        如果(无效== 0)
        {
            //计算的电阻值
            resistor_value = calResistance(彩色[0],彩色[1],颜色[2]);
            //印刷电阻值用户
            的printf(%0F \\ n,resistor_value);
            print_number(resistor_value);
        }
        的printf(你想脱code另一个电阻(Y / N)\\ n吗?);
        得到(状态);
        如果(的strcmp(状态,Y)== 0);
        别人休息;
    }
    返回0;
}
INT inputVal为(int *一个,炭B〔3] [10])
{
    INT计数器= 0,索引[3];
    对(INT I = 0;我3; ++ⅰ)
    {
        如果(一个由[i] == 10)
        {
            指数[i] =我;
            //的printf(%s%S,B [I],);
            反++;
        }
    }
    如果(反== 0)
    {
        返回0;
    }
    否则如果(计数器== 1)
    {
        的printf(无效的颜色:%S \\ n,B [指数[0]);
    }
    否则如果(计数器== 2)
    {
        的printf(无效的颜色:);
        的printf(%S,B [指数[0]);
        输出(,);
        的printf(%S \\ n,B [指数[1]);
    }
    其他
    {
        的printf(无效的颜色:);
        的printf(%S,B [指数[0]);
        输出(,);
        的printf(%S,B [指数[1]);
        输出(,);
        的printf(%S \\ n,B [指数[2]);
    }
    返回1;
}双calResistance(INT A,INT B,INT C)
{
    双重效果;
    无符号的功率= 10;
    而(B> =功率)
    {
        电* = 10;
    }
    结果= A *电源+ B;
    结果=结果* POW(10,C);
    返回结果;
}无效print_number(双号)
{
    双N =号,* X;
    INT C = 0;
    INT J = 1;
    而(N = 0安培;!&放大器; N大于1)
    {        N / = 10.0;        C + = 1;
    }
    X =的malloc(C *的sizeof(双));
    的printf(%d个\\ N,C);    的for(int i = 0; I< = C;我++)
     {
        两位数= FMOD(数字,10.0);
        X [i] =数字;
        数/ = 10.0;
     }     的printf(电阻值:\\ n \\ n);     对于(INT I = C - 1; I> = 0;我 - )
     {
        的printf(#%D =剩余%.0f \\ n,I,X [I]);
     }
    的printf(\\ n \\ n \\ n);    对于(INT I = C - 1; I> = 0;我 - )
    {        如果(J == || 3 ==Ĵ7 ||Ĵ== || 11 ==Ĵ15)
        {
            的printf();
        }
        其他
        {
            的printf(%0F,X [I]);
        }
        J ++;
    }
    的printf(-ohms \\ n);
    //自由(X);
}

我已经编辑了print_number功能,所以它打印每3位的空间。 (它的工作原理与大多数组合)

 无效print_number(双号)
{
    双N =号,* X;
    INT C = 0;
    INT J = 1;
    而(N = 0安培;!&放大器; N大于1)
    {        N / = 10.0;        C + = 1;
    }
    X =的malloc(C *的sizeof(双));
    的printf(C =%d个\\ N,C);
    的for(int i = 0;我c为C;我++)
     {
        两位数= FMOD(数字,10.0);
        X [i] =数字;
        数/ = 10.0;
     }     的printf(电阻值:\\ n);     的for(int i = C:I> = 0;我 - )
     {
        的printf(#%D =剩余%.0f \\ n,I,X [I]);
     }
     的printf(\\ n \\ n);
     的printf(C的余数=%d个\\ n \\ n,C%3);
    如果(C%3 == 2)
    {
        的for(int i = C:I> = 0;我 - )
        {
            如果(J == || 4 ==Ĵ7 ||Ĵ== || 11 ==Ĵ15)
                {
                    的printf();
                    我++;
                }
                其他
                {
                    的printf(%0F,X [I]);
                }
            J ++;
        }
        的printf(-ohms \\ n);
    }
    其他
    {
        对于(INT I = C - 1; I> = 0;我 - )
        {
            //printf(\"%.0f中,x [I]);            如果(C%3 == 0)
            {
                如果(J == || 4 ==Ĵ8 ||Ĵ== || 12 ==Ĵ16)
                {
                    的printf();
                    我++;
                }
                其他
                {
                    的printf(%0F,X [I]);
                }
            }
            否则如果(C%3 == 1)
            {
                如果(J == 2 ||Ĵ== || 6 ==Ĵ10 ||Ĵ== 14)
                {
                    的printf();
                    我++;
                }
                其他
                {
                    的printf(%0F,X [I]);
                }
            }
            J ++;
        }
        的printf(-ohms \\ n);
        //自由(X);
    }
}

版本2

下面从答案修改code。
我没有使用的原因 ARGC 的argv 是客户端有一个需要followd受限格式(这驱使我疯了!)

这里是code:

  //导入需要的头文件
#包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&math.h中GT;//电阻带
枚举resistor_band_items {黑,棕,红,橙,黄,绿,
                                 蓝色,紫色,灰色,白色,UNKNOWN};//最小/最大色彩参数和最大色彩焦炭常数
枚举{MINC = 3,MAXC = 4,MAXCC = 8};
项目结构
 {
    字符*名称;
    枚举resistor_band_items ID;
 } item_list [] = {
    {黑,BLACK},
    {棕色,布朗},
    {红,红},
    {橙色,ORANGE},
    {黄,黄色},
    {绿色,绿色},
    {蓝,蓝},
    {紫罗兰,VIOLET},
    {灰色,灰色},
    {白,白}
};
//电阻乘数值
INT乘数[] = {1,10,100,1000,10000,100000,1000000千万};
炭答案[3] [10]; //用户输入
INT colour_val [3]; //存储区值#定义NITEMS个(sizeof的item_list / sizeof的* item_list)
//功能prototyps
INT srchItems(字符* C code); //为索引值搜索
字符* strcpy2lower(字符* DEST,字符* SRC); //转换为小写
INT SCMP(字符*一,字符* B); //简单的字符串comarison
字符* sepnumber(字符* S,长VAL);
INT无效(炭答案[3] [10]);
//主要功能
INT主(INT ARGC,字符常量*的argv [])
{
    INT I; //计数器
    焦状态='Y'; //保存程序运行时用户输入Y
    长resistor_value = 0; //总电阻
    INT R,呃,MULT; //持有显著的身影,错误乘数
    烧焦resistor_value_string [20] =; //格式化输出
    而(状态=='Y')//方案下运行这个
    {
        //打印问题向用户
        的printf(请输入电阻器的三个频段的颜色,\\与乐队nbeginning最接近最终\\ n类型以小写字母只,缺盖的coloues \\ n。);
        对于(i = 0; I< MINC ++ I)
        {
            的printf(%乐队D =>中,I + 1); //为每个条带打印头
            scanf函数(%S,&安培;回答[I]); //获取用户输入
        }
        对于(i = 0; I< MINC - 1 ++ I)//转换色入指数
        {
            如果((R = srchItems(回答由[i]))&-1)〜
            {
                //从显著图
                resistor_value =(resistor_value * 10)+ R;
            }
            其他
            {
                无效的(答案);
                ERR = 2;            }
        }
        如果(ERR→1)
        {
            的printf(你想脱code anothe电阻(Y / N)\\ n吗?);
            scanf函数(%C,&安培;状态);
            如果(状态=='Y');
            别人休息;
        }
        其他
        {
            MULT = srchItems(答案[I]); //取得事半功倍的指数
            resistor_value * =乘数[多个]; //计算终值            sepnumber(resistor_value_string,resistor_value);
            的printf(电阻值:);
            / *的for(int i = 0;我≤(strlen的(resistor_value_string)); ++ I)
            {
                的printf(%C,resistor_value_string [I]);
            }
            * /
            看跌期权(resistor_value_string);
            //输出(-ohm \\ n);
            // memset的(resistor_value_string,0,50);
            的printf(你想脱code anothe电阻(Y / N)\\ n吗?);
            scanf函数(%C,&安培;状态);
            如果(状态=='Y');
            别人休息;
            / *调试
            的for(int i = 0; I< MINC ++ I)
            {
                的printf(item_list [%d个=%S \\ n,我回答[I]);
            }
            的printf(总电阻=%LD \\ N,resistor_value);
            //调试结束* /
        }
    }
    返回0;
}INT srchItems(字符* C code)
{
    INT I;
    焦炭LC code [MAXCC] =;
    strcpy2lower(LC code,C code); //一切转换为小写
    对(INT I = 0; I&≤(INT)NITEMS个++ⅰ)
        如果(* LC code == *(item_list [我]。名称))
            如果(!南华早报(item_list [I] .name和LC code)条)
                返回我;
    返回-1;
}字符* strcpy2lower(字符* DEST,字符* SRC)
{
    如果返回NULL(SRC || DEST!);
    字符* D = DEST;
    对于(* SRC; SRC +,D ++)
        如果('A'< = * SRC&放大器;&放大器; * SRC< ='Z')
            * D = * SRC | (1 <<;小于5);
        其他
            * D = * SRC;
    * D = 0;
    返回DEST;
}INT SCMP(字符*一,字符* B)
{
    如果(A和!&安培;!B)返回0;
    如果(A&安培;&安培;!b)退回1;
    如果(A和!和b)返回-1;    对于(* A和&放大器; * B和;&放大器; *一* == B; A ++,B ++){}    返回一个* - * B;
}
/ **独立长值每3个焦炭引入的'* /
字符* sepnumber(字符* S,长VAL)
{
    炭numstr [3 * MAXCC] =;
    的char * p = numstr;
    为size_t IDX = 0,LEN = 0;    sprintf的(numstr,%LD,VAL);
    为(; * P,P ++){}
    LEN = P - numstr;
    P = S + 3 * MAXCC - 2;    而(len--){
        如果(IDX ++ == 3){
            IDX = 1;
            * P-- ='';
        }
        * P = numstr [LEN]
        如果(LEN)P--;
    }
    对于(IDX = 0; * P,P ++,IDX ++)S [IDX] = * P; / *复制到S * /
    S [IDX] = * P; / * NUL,终止* /
    返回S;
}诠释无效(炭答案[3] [10])
{
    INT R,计数器= 0时,不正确[3],I;    对于(i = 0; I&LT; MINC ++ I)
    {
        如果((R = srchItems(回答由[i]))== - 1)
        {
            不正确[I] = R;
            反++;
        }
    }
    如果(计数器== 1)
    {
        的printf(%S,无效的颜色:);
        的printf(%S,回答[I]);
        的printf(\\ n);
    }
    I = 0;
}

这转行之有效的第一个循环,但它计算在第二循环开始了错误的电阻值。
这将打印带有一点困难无效的条目!
经过一个无效的颜色被输入程序将不会计算任何电阻值。

OUT输出的例子:

  $ ./RQ1.exe
输入电阻器的三个频段的颜色,
与带开始最接近端。
键入小写字母只,NO CAPS的coloues。
波段1 =&GT;红
带2 =&GT;橙子
带3 =&GT;绿色
电阻值:2 300 000
你想脱code anothe电阻(Y / N)?
ÿ
输入电阻器的三个频段的颜色,
与带开始最接近端。
键入小写字母只,NO CAPS的coloues。
波段1 =&GT;绿色
带2 =&GT;黑色
带3 =&GT;黄色
电阻值:-2 101 970 656
你想脱code anothe电阻(Y / N)?
ÿ
输入电阻器的三个频段的颜色,
与带开始最接近端。
键入小写字母只,NO CAPS的coloues。
波段1 =&GT;读
带2 =&GT;格伦
带3 =&GT;蓝光
你想脱code anothe电阻(Y / N)?
ÿ
输入电阻器的三个频段的颜色,
与带开始最接近端。
键入小写字母只,NO CAPS的coloues。
波段1 =&GT;红
带2 =&GT;橙子
带3 =&GT;绿色
你想脱code anothe电阻(Y / N)?
ñ

的最终版本,

我觉得这是它:)事实上,它仍然有显示无效的投入问题的身边。

一个真正的大坦克大卫C.兰的帮助了这么多。

 的#include&LT;&stdio.h中GT;
#包括LT&;&string.h中GT;#定义NITEMS个(sizeof的item_list / sizeof的* item_list)焦状态='Y';
//
枚举{MINC = 3,MAXCC = 10};
//电阻带
枚举resistor_band_items {黑,棕,红,橙,黄,绿,
                                 蓝色,紫色,灰色,白色,UNKNOWN};
项目结构
 {
    字符*名称;
    枚举resistor_band_items ID;
 } item_list [] = {
    {黑,BLACK},
    {棕色,布朗},
    {红,红},
    {橙色,ORANGE},
    {黄,黄色},
    {绿色,绿色},
    {蓝,蓝},
    {紫罗兰,VIOLET},
    {灰色,灰色},
    {白,白}
};
无符号整型乘数[] = {1,10,100,1000,10000,100000,1000000
     10000000亿,10亿};INT srchItems(字符* C code); //为索引值搜索
字符* strcpy2lower(字符* DEST,字符* SRC); //转换为小写
INT SCMP(字符*一,字符* B); //简单的字符串comarison
字符* sepnumber(字符* S,长VAL); //把空间的每个第3位INT主要(无效)
{
    INT I,错误= 0,MULT;
    字符输入[MINC] [MAXCC]; //用户输入
    字符无效[MINC] [MAXCC]; //无效enteries
    INT colour_val [MINC] //存储区值
    长total_resistance = 0;
    烧焦resistor_value_string [20] =; //格式化输出
    做
    {
    //用户提示
    的printf(%S \\ n%S \\ n%S \\ n,
        输入电阻器的三个波段的颜色,
        开始向邻近结束的乐队。
        以小写字母键入唯一的颜色,没有端点。);    对于(i = 0; I&LT; MINC ++ I)
    {
        的printf(%乐队D =&gt;中,I + 1); //为每个条带打印头
        scanf函数(%S,和放大器;输入[I]); //获取用户输入
        //用户输入转换为颜色索引
        colour_val [I] = srchItems(输入[I]);
    }
    对于(i = 0; I&LT; MINC ++ I)
    {
        如果(colour_val [I] == -1)
        {
            的strcpy(无效[I]中,输入由[i]);
            错误++;
        }
    }
    如果(误差大于0)
    {
        如果(错误== 1)
        {
            的printf(无效的颜色:%S \\ N的,无效的[0]);
        }
        否则如果(错误== 2)
        {
            的printf(无效的颜色:%S%S \\ N的,无效的[0]无效[1]);
        }
        其他
        {
            的printf(无效的颜色:%S%S%S \\ n,
             无效[0],无效[1],无效[2]);
        }
    }
    其他
    {
        //
        对于(i = 0; I&LT; MINC - 1 ++ I)
        {
            total_resistance =(total_resistance * 10)+ colour_val [I]
        }
        MULT = [2] colour_val;
        total_resistance * =乘数[多个];
        sepnumber(resistor_value_string,total_resistance);        的printf(电阻值:%s的-Ohms \\ n,resistor_value_string);
//调试
        对于(i = 0; I&LT; MINC ++ I)
        {
            //的printf(输入==&GT;%S \\ T,输入[I]);
            //输出(指数==&GT;%d个\\ N,colour_val [I]);
        }
//结束调试
    }
    误差= 0;
    total_resistance = 0;
    对于(i = 0; I&LT; MINC ++ I)
    {
        colour_val [I] = 0;
    }
    //询问用户是否要继续
    的printf(你想脱code另一个电阻\\ n吗?);
    scanf函数(%C,&安培;状态);
    如果(状态=='Y');
    别人休息;    }而(状态=='Y');    返回0;
}INT srchItems(字符* C code)
{
    INT I;
    焦炭LC code [MAXCC] =;
    strcpy2lower(LC code,C code); //一切转换为小写
    对(INT I = 0; I&≤(INT)NITEMS个++ⅰ)
        如果(* LC code == *(item_list [我]。名称))
            如果(!南华早报(item_list [I] .name和LC code)条)
                返回我;
    返回-1;
}字符* strcpy2lower(字符* DEST,字符* SRC)
{
    如果返回NULL(SRC || DEST!);
    字符* D = DEST;
    对于(* SRC; SRC +,D ++)
        如果('A'&LT; = * SRC&放大器;&放大器; * SRC&LT; ='Z')
            * D = * SRC | (1 <<;小于5);
        其他
            * D = * SRC;
    * D = 0;
    返回DEST;
}INT SCMP(字符*一,字符* B)
{
    如果(A和!&安培;!B)返回0;
    如果(A&安培;&安培;!b)退回1;
    如果(A和!和b)返回-1;    对于(* A和&放大器; * B和;&放大器; *一* == B; A ++,B ++){}    返回一个* - * B;
}/ **独立长值每3个焦炭引入的'* /
字符* sepnumber(字符* S,长VAL)
{
    炭numstr [3 * MAXCC] =;
    的char * p = numstr;
    为size_t IDX = 0,LEN = 0;    sprintf的(numstr,%LD,VAL);
    为(; * P,P ++){}
    LEN = P - numstr;
//的printf(%d个\\ N,LEN);
    P = S + 3 * MAXCC - 2;    而(len--){
        如果(IDX ++ == 3){
            IDX = 1;
            * P-- ='';
        }
        * P = numstr [LEN]
        如果(LEN)P--;
    }
    对于(IDX = 0; * P,P ++,IDX ++)S [IDX] = * P; / *复制到S * /
    S [IDX] = * P; / * NUL,终止* /
    返回S;
}

输出例如

  $ ./Q1_token.exe
输入电阻器的三个频段的颜色,
与带开始最接近端。
键入小写字母只,缺盖的颜色。
波段1 =&GT;绿色
带2 =&GT;黑色
带3 =&GT;黄色
电阻值:500 000 -Ohms
你想脱code另一电阻?
ÿ
输入电阻器的三个频段的颜色,
与带开始最接近端。
键入小写字母只,缺盖的颜色。
波段1 =&GT;红
带2 =&GT;橙子
带3 =&GT;绿色
电阻值:2 300 000 -Ohms
你想脱code另一电阻?
ÿ
输入电阻器的三个频段的颜色,
与带开始最接近端。
键入小写字母只,NO CAPS的coloues。
波段1 =&GT;粉
带2 =&GT;银
带3 =&GT;红
无效的颜色:粉色,银色
你想脱code另一电阻?
ÿ
输入电阻器的三个频段的颜色,
与带开始最接近端。
键入小写字母只,缺盖的颜色。
波段1 =&GT; vilot
带2 =&GT;棕色
带3 =&GT;读
无效的颜色:vilot,银
你想脱code另一电阻?
ñ


解决方案

您code,用于确定您的电阻值显著数字比需要更多的复杂不少。既然你声明结构的全局数组 item_list ,所有你需要做的形成显著图是使用 item_list 作为一个查找表以找到输入的带颜色的索引。对于随后的每个颜色(第2 [3和5段]),你只需添加索引之前乘以 10 当前的电阻值。

例如与 item_list 指标变量研究和电阻值 RVAL (包括你的支票无效的颜色),您的code可以简化为:

  INT乘数[] = {1,10,100,1000,10000,100000,1000000千万};
...
    INT ERR = 0,I,MULT,R;
    长RVAL = 0;    的printf(\\ ncolor乐队确定显著数字:\\ n \\ n);
    对于(i = 1; I&LT; ARGC - 1;我++){/ *转换颜色索引* /
        如果((R = srchitems(的argv [I]))!= -1){
            RVAL = RVAL * 10 + R; / *形式显著图* /
            prnitem(R);
        }
        其他{
            fprintf中(标准错误,错误:无效的颜色'%s'的\\ n,argv的[I]);
            ERR = 1;
        }
    }
    如果(ERR)返回1;
    MULT = srchitems(的argv [I]); / *取得事半功倍的指数* /
    RVAL * =乘数[多个]; / * calculare终值* /
    的printf(\\ nmultiplier:\\ n \\ n);
    prnitem(多重);
    的printf(\\ nresistor值:%ld的-ohms \\ n \\ n,RVAL);    返回0;

以上的 srchitems 函数简单的返回指数 item_list 给出一个颜色(作为参数输入到程序,例如:的argv [1] 的argv [2] ......),你可以写一个简单的 srchitems 可以转换所有输入$ p $之前小写pforming查找为:

  / **搜索item_list颜色code'C code',回报指数
 *成功返回数组索引,否则为-1。
 * /
INT srchitems(字符* C code)
{
    INT I;
    焦炭LC code [MAXCC] =; / *数组来保存彩色小写* /    strcpy2lower(LC code,C code); / *字符串转换为小写* /    对于(I = 0; I&≤(INT)NITEMS个;我++)/ *查找索引* /
        如果(* LC code == *(item_list [我]。名称))
            如果(!南华早报(item_list [I] .name和LC code)条)
                返回我;    返回-1; / *返回-1错误* /
}

如果你把拼图的剩余拼在一起,你可以做类似如下的东西。我让你根据需要格式化输出。您可以取代简单的字符串比较函数南华早报 STRCMP (和包括 string.h中)让我知道,如果你有任何问题。

 的#include&LT;&stdio.h中GT;/ *电阻带* /
枚举resistor_band_items {黑,棕,红,橙,黄,绿,
                        蓝色,紫色,灰色,白色,UNKNOWN};
/ *常数最小/最大色彩参数和最大彩色字符* /
枚举{MINC = 3,MAXC = 4,MAXCC = 8};结构件/ *可能是字符串的简单数组* /
{
    字符*名称;
    枚举resistor_band_items ID;
} item_list [] = {
    {黑,BLACK},
    {棕色,布朗},
    {红,红},
    {橙色,ORANGE},
    {黄,黄色},
    {绿色,绿色},
    {蓝,蓝},
    {紫罗兰,VIOLET},
    {灰色,灰色},
    {白,白}
};
/ *电阻乘数值* /
INT乘数[] = {1,10,100,1000,10000,100000,1000000千万};#定义NITEMS个(sizeof的item_list / sizeof的* item_list)INT srchitems(字符* C code);
字符* strcpy2lower(字符* DEST,字符* SRC);
INT SCMP(字符*一,字符* B);
无效prnitem(INT I);INT主(INT ARGC,字符** argv的){    如果(ARGC&LT; MAXC || MAXC±1℃; ARGC){/ *检查3或4个参数* /
        fprintf中(标准错误,错误:无效的输入,用法:%s的C1,C2,C3 [4] \\ n
                         用法:进入颜色codeS为4或5段的电阻\\ n
                         (公差忽略,进入4种颜色的最大值)\\ n
                        的argv [0]);
        返回1;
    }    INT ERR = 0,I,MULT,R;
    长RVAL = 0;    的printf(\\ ncolor乐队确定显著数字:\\ n \\ n);
    对于(i = 1; I&LT; ARGC - 1;我++){/ *转换颜色索引* /
        如果((R = srchitems(的argv [I]))!= -1){
            RVAL = RVAL * 10 + R; / *形式显著图* /
            prnitem(R);
        }
        其他{
            fprintf中(标准错误,错误:无效的颜色'%s'的\\ n,argv的[I]);
            ERR = 1;
        }
    }
    如果(ERR)返回1;
    MULT = srchitems(的argv [I]); / *取得事半功倍的指数* /
    RVAL * =乘数[多个]; / * calculare终值* /
    的printf(\\ nmultiplier:\\ n \\ n);
    prnitem(多重);
    的printf(\\ nresistor值:%ld的-ohms \\ n \\ n,RVAL);    返回0;
}/ **搜索item_list颜色code'C code',回报指数
 *成功返回数组索引,否则为-1。
 * /
INT srchitems(字符* C code)
{
    INT I;
    焦炭LC code [MAXCC] =;    strcpy2lower(LC code,C code);    对于(I = 0; I&≤(INT)NITEMS个;我+ +)
        如果(* LC code == *(item_list [我]。名称))
            如果(!南华早报(item_list [I] .name和LC code)条)
                返回我;    返回-1;
}/ **复制和字符串转换为小写。
 *返回字符串的复制与转换为小写字符的所有。
 *(DEST必须是持有SRC的足够的大小)
 * /
字符* strcpy2lower(字符* DEST,字符* SRC)
{
    如果返回NULL(SRC || DEST!);    字符* D = DEST;    对于(* SRC; SRC +,D ++)
        如果('A'&LT; = * SRC&放大器;&放大器; * SRC&LT; ='Z')
            * D = * SRC | (1 <<;小于5);
        其他
            * D = * SRC;    * D = 0;    返回DEST;
}/ **简单的字符串比较(如STRCMP)* /
INT SCMP(字符*一,字符* B)
{
    如果(A和!&安培;!B)返回0;
    如果(A&安培;&安培;!b)退回1;
    如果(A和!和b)返回-1;    对于(* A和&放大器; * B和;&放大器; *一* == B; A ++,B ++){}    返回一个* - * B;
}无效prnitem(int i)以
{
    的printf(item_list [%D]。名称:%-6S ID:%d个\\ N,
            我,item_list [I] .name和item_list [I] .ID);
}

示例使用/输出

有效电阻颜色(大写或小写字符都很好)

  $ ./bin/resistor绿蓝黄色带确定显著的数字: item_list [5]名称:绿色ID:5
 item_list [6]名称:蓝ID:6乘数: item_list [4]的名字:黄ID:4电阻值:560000 -ohms
$ ./bin/resistor红色橙色紫色黑色带确定显著的数字: item_list [2]的名字:红ID:2
 item_list [3]的名字:橙色ID:3
 item_list [7]名:紫ID:7乘数: item_list [0]名称:黑色ID:0电阻值:237 -ohms

无效的颜色生成单独的错误:

  $ ./bin/resistor粉色银色绿色色带确定显著的数字:错误:无效的颜色粉红
错误:无效的色彩银

分割数每三个字符

而不是在这里你是依靠数字计算测试/分开你的号码一个相当复杂的方法,为什么不转换您的数量来的字符串(无小数位)然后只需向后从最终复制的字符工作一个新的字符串,并添加空格每3个字?这使事情变得轻松许多。 (即使你使用的是双击对于一些闻所未闻的 - 原因 - 假设你最终将合并公差)这真的让这种做法没有什么区别。给出如下尝试:

 无效print_number(双号)
{
    炭numstr [3 * MAXCC] =,sepstr [3 * MAXCC] =;
    的char * p = NULL;
    为size_t IDX = 0,LEN = 0;    sprintf的(numstr,%.0lf号); / *写双串* /
    LEN = strlen的(numstr); / *获取长度* /
    p值= sepstr + 3 * MAXCC - 2; / *集合P在sepstr最后一个字符* /    而(len--){/ *为每个numstr的char * /
        如果(IDX ++ == 3){/ *如果3个字符复制* /
            IDX = 1; / *复位指数* /
            * P-- =''; / *在sepstr写一个空格* /
        }
        * P = numstr [LEN]在sepstr / *写的char * /
        如果(LEN)P--; / *递减p如果不为0 * /
    }    的printf(P:'%s'的\\ n,p)的; / *打印单独的值* /
}

注意,你可以简单地传递一个字符数组 print_number 复制 P 到数组,如果你想使现有的阵列早在格式化的原因(你甚至可以改变 print_number 来在这种情况下返回的char * )。让我知道,如果它的工作原理。如果你不能这样做的,然后我会通过你的数字逻辑正常工作,但将服用阿司匹林并很可能会在早上:)

示例 print_number 输出

  5 =&GT; '5'
          55 =&GT; '55'
         555 =&GT; 555
        5555 =&GT; 5 555
       55555 =&GT; '55 555
      555555 =&GT; 555 555
     5555555 =&GT; 5 555 555
    55555555 =&GT; 1955 555 555
   555555555 =&GT; 555 555 555

实际执行示例

下面是我实现它变成我的code的方式。从本质上讲,你只需动 sepstr 报关/初始化成,然后把它作为一个数组来你的 print_number (我的 sepnumber 下面)。

 的char * sepnumber(字符* S,长VAL);
...
    长RVAL = 0;
    炭RSTR [3 * MAXCC] =;
    ...
    的printf(\\ nresistor值:%s的-ohms \\ n \\ n,sepnumber(RSTR,RVAL));    返回0;
}
...
/ **独立长值每3个焦炭引入的'* /
字符* sepnumber(字符* S,长VAL)
{
    炭numstr [3 * MAXCC] =;
    的char * p = numstr;
    为size_t IDX = 0,LEN = 0;    sprintf的(numstr,%LD,VAL);
    为(; * P,P ++){}
    LEN = P - numstr;
    P = S + 3 * MAXCC - 2;    而(len--){
        如果(IDX ++ == 3){
            IDX = 1;
            * P-- ='';
        }
        * P = numstr [LEN]
        如果(LEN)P--;
    }
    对于(IDX = 0; * P,P ++,IDX ++)S [IDX] = * P; / *复制到S * /
    S [IDX] = * P; / * NUL,终止* /    返回S;
}

示例/输出

  $ ./bin/resistor绿蓝黄色带确定显著的数字: item_list [5]名称:绿色ID:5
 item_list [6]名称:蓝ID:6乘数: item_list [4]的名字:黄ID:4电阻值:560 000 -ohms
$ ./bin/resistor红橙紫褐色色带确定显著的数字: item_list [2]的名字:红ID:2
 item_list [3]的名字:橙色ID:3
 item_list [7]名:紫ID:7乘数: item_list [1]名称:棕色ID:1电阻值:2 370 -ohms

重新初始化值当循环输入

由于您的问题描述,我强烈怀疑您遇到的问题是,由于没有复位/重新初始化 RVAL = 0; (你的 resistor_value ),在每个循环的末尾(或一些类似的值)。经常检查其值可能是添加剂等并记住这些值在每个循环的开始复位。在大多数情况下,以处理这另一种方法是循环的范围内声明变量,使得它们自动重新初始化每次迭代

使用块范围的循环,你的应该是类似以下内容:

  INT主要(无效){    为(;;){/ *循环输入* /
        INT ERR = 0,I,MULT,R; / *变量有块范围仅* /
        长RVAL = 0;
        焦C code [MAXCC] =,RSTR [3 * MAXCC] =;        的printf(\\ n输入电阻器的三个频段的颜色,\\ n
                与乐队开始最接近结束\\ n);
        对于(i = 0; I&LT; MINC,我++){/ *转换颜色索引* /
            的printf(%乐队D =&gt;中,I + 1);
            如果(scanf函数(%7S,C code)!= 1){
                fprintf中(标准错误,错误:无效的输入或EOF \\ n);
                返回1;
            }
            如果((R = srchitems(C code))!= -1){
                如果(ⅰ2){
                    RVAL = RVAL * 10 + R; / *形式显著图* /
                }
                其他{
                    MULT = srchitems(C code); / *取得事半功倍的指数* /
                    RVAL * =乘数[多个]; / * calculare终值* /
                }
            }
            其他{
                fprintf中(标准错误,错误:无效的颜色'%s'的\\ n,C code);
                ERR = 1;
            }
        }
        如果(ERR)返回1;
        的printf(的电阻值:%s的-ohms \\ n,sepnumber(RSTR,RVAL));
        的printf(\\ n您想取消code另一个电阻(Y / N)?);
        如果(scanf函数(%7S,C code)!= 1){
            fprintf中(标准错误,错误:无效的输入或EOF \\ n);
            返回1;
        }
        如果(* C code ='Y'和;!&放大器; * C code ='Y'!)破;
    }    返回0;
}

示例使用/输出

  $ ./bin/resistor2输入电阻器的三个频段的颜色,
与带开始最接近端。
波段1 =&GT;绿色
带2 =&GT;蓝色
带3 =&GT;黄色
电阻值:560 000 -ohms你想脱code另一个电阻(Y / N)? ÿ输入电阻器的三个频段的颜色,
与带开始最接近端。
波段1 =&GT;红
带2 =&GT;橙子
带3 =&GT;橙子
电阻值:23 000 -ohms你想脱code另一个电阻(Y / N)? ñ

我怀疑你可以用这个提示找到你的错误。

I'm trying to develop a C program that calculates the resistor values by inputting the colour bands marked on the resistor.

Ignoring the resistor tolerance.

e.g.

Enter the colours of the resistor’s three bands, beginning
with the band nearest the end. Type the colours in lowercase
letters only, NO CAPS
Band 1 => green
Band 2 => black
Band 3 => yellow
Resistance value: 500 000 -ohms
Do you want to decode another resistor (Y/N)?
=> Y 

  1. Displaying the required format of the resistor value. For example, if the resistor value is "500000 -ohms", the format is required to be "500 000 -ohms". A space has to be put between every 3 digits.
  2. Displaying a single invalid colour. For example, if 'brown', 'vilet', and 'red' are inputted as the resistor colours, the program generates the following message: Invalid colour: vilet Here only 'vilet' is the only invalid colour.
  3. Displaying more than one invalid colour. For example, if 'pink', 'silver', and 'red' are inputted as the resistor colours, the program should generate the following message in a single line: Invalid colours: pink, silver Here are two invalid colours 'pink' and 'silver'. Note the 'colours'.

Now I'm having a difficult time with getting the formatting for the total resistance (#1). And for #2 & #3 if and only if the first input (band 1) is invalid the program will run. If the second band or third band are invalid without the first band being invalid, the program will stop execution.

Here is the code that I've been working on:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

// resister bands
enum resistor_band_items {BLACK, BROWN, RED, ORANGE, YELLOW, GREEN, BLUE, VIOLET, GRAY, WHITE, UNKNOWN};

struct items
 {
    char *name;
    enum resistor_band_items id;
 } item_list[] = {
    {"black", BLACK},
    {"brown", BROWN},
    {"red", RED},
    {"orange", ORANGE},
    {"yellow", YELLOW},
    {"green", GREEN},
    {"blue", BLUE},
    {"violet", VIOLET},
    {"gray", GRAY},
    {"white", WHITE}
};

char answer[10], status[1] = "Y"; //answer => user input
char bands[3][10];      //string for resistor bands
//variables to hold the band values
int colour[3];
//function prototype
int inputVal (int *a, char b[3][10]);
double calResistance (int a, int b, int c);
void print_number (double number);

int main(void)
{
    int i, invalid; //counter
    double resistor_value; //total resistance value
    enum resistor_band_items mid;
    struct items *choice = NULL;

    while (strcmp(status, "Y") == 0)
    {
        //print the question to the user
        printf("Enter the colours of the resistor's three bands,\nbeginning with the band nearest to the end.\nType the coloues in lowercase letters only, NO CAPS.\n");    
        for (int j = 0; j<3; j++)
        {   
            printf("Band %d => ", j + 1);
            gets(answer);
            for (i = 0, choice = NULL; i < sizeof item_list/sizeof(struct items); ++i)
            {
                if (strcmp(answer, item_list[i].name) == 0)
                {
                    choice = item_list + i;
                    break;
                }
            }
            mid = choice ? choice ->id : UNKNOWN;
            colour[j] =  mid;
            strcpy(bands[j], answer);
        }
        invalid = inputVal (colour, bands);
        if (invalid == 0)
        {
            //calculate resistor value
            resistor_value = calResistance(colour[0], colour[1],colour[2]);
            // print resistor value to user
            printf("%.0f\n", resistor_value);
            print_number(resistor_value);
        }
        printf("Do you want to decode another resistor (Y/N)?\n");
        gets(status);
        if (strcmp(status, "Y") == 0);
        else break;
    }   
    return 0;
}
int inputVal (int *a, char b[3][10])
{
    int counter = 0, index[3];
    for (int i = 0; i < 3; ++i)
    {
        if (a[i] == 10)
        {
            index[i] = i;
            //printf("%s%s", b[i], " ");
            counter++;
        }
    }
    if (counter == 0)
    {
        return 0;
    }
    else if (counter == 1)
    {
        printf("Invalid colour: %s\n", b[index[0]]);
    }
    else if (counter == 2)
    {
        printf("Invalid colours:");
        printf(" %s", b[index[0]]);
        printf(",");
        printf(" %s\n", b[index[1]]);
    }
    else
    {
        printf("Invalid colours:");
        printf(" %s", b[index[0]]);
        printf(",");
        printf(" %s", b[index[1]]); 
        printf(",");
        printf(" %s\n", b[index[2]]);   
    }
    return 1;
}

double calResistance (int a, int b, int c)
{
    double results;
    unsigned power = 10;
    while (b >= power)
    {
        power *= 10;
    }
    results = a * power + b;
    results = results * pow(10, c);
    return results;
}

void print_number (double number)
{
    double n = number,  *x;
    int c = 0;
    int j = 1;
    while   (n != 0 && n > 1)
    {

        n /= 10.0;

        c += 1;
    }
    x = malloc (c * sizeof(double));
    printf("%d\n", c);

    for (int i = 0; i <= c; i++)
     {
        double digit = fmod (number, 10.0);
        x[i] = digit;
        number /= 10.0;
     }

     printf("Resistance value: \n\n"); 

     for (int i = c - 1; i >= 0; i--)
     {
        printf("#%d = %.0f\n",i, x[i]);
     }
    printf("\n\n\n");

    for (int i = c - 1; i >= 0; i--)
    {

        if (j == 3 || j == 7 || j == 11 || j == 15)
        {
            printf(" ");
        }
        else
        {
            printf("%.0f", x[i]);
        }
        j++;
    }
    printf(" -ohms\n");
    //free(x);
}

I've edited the print_number function so it prints a space every 3rd digit. (It works with most combinations)

void print_number (double number)
{
    double n = number,  *x;
    int c = 0;
    int j = 1;
    while   (n != 0 && n > 1)
    {

        n /= 10.0;

        c += 1;
    }
    x = malloc (c * sizeof(double));
    printf("c = %d\n", c);
    for (int i = 0; i < c; i++)
     {
        double digit = fmod (number, 10.0);
        x[i] = digit;
        number /= 10.0;
     }

     printf("Resistance value: \n"); 

     for (int i = c; i >= 0; i--)
     {
        printf("#%d = %.0f\n",i, x[i]);
     }
     printf("\n\n");
     printf("remainder of c = %d\n\n",c%3);
    if (c % 3 == 2)
    {
        for (int i = c; i >= 0; i--)
        {
            if (j == 4 || j == 7 || j == 11 || j == 15)
                {
                    printf(" ");
                    i++;
                }
                else
                {
                    printf("%.0f", x[i]);
                }
            j++;
        }
        printf(" -ohms\n"); 
    }
    else
    {
        for (int i = c - 1 ; i >= 0; i--)
        {
            //printf("%.0f", x[i]);

            if (c % 3 == 0)
            {
                if (j == 4 || j == 8 || j == 12 || j == 16)
                {
                    printf(" ");
                    i++;
                }
                else
                {
                    printf("%.0f", x[i]);
                }
            }
            else if (c % 3 == 1)
            {
                if (j == 2 || j == 6 || j == 10 || j == 14)
                {
                    printf(" ");
                    i++;
                }
                else
                {
                    printf("%.0f", x[i]);
                }
            }   
            j++;
        }
        printf(" -ohms\n");
        //free(x);      
    }
}

Rev 2

Here the modified code from the answers. The reason I'm not using argcand argvis that the client has a restricted formatting that needs to be followd (Which drives me mad!)

here is the code:

    //importing required header files
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

// resister bands
enum resistor_band_items {BLACK, BROWN, RED, ORANGE, YELLOW, GREEN,
                                 BLUE, VIOLET, GRAY, WHITE, UNKNOWN};

//constants for min/max colour arguments and max colour char
enum {MINC = 3, MAXC = 4, MAXCC = 8};
struct items
 {
    char *name;
    enum resistor_band_items id;
 } item_list[] = {
    {"black", BLACK},
    {"brown", BROWN},
    {"red", RED},
    {"orange", ORANGE},
    {"yellow", YELLOW},
    {"green", GREEN},
    {"blue", BLUE},
    {"violet", VIOLET},
    {"gray", GRAY},
    {"white", WHITE}
};
//resistor multiplier values
int multiplier[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};
char answer[3][10]; // User input
int colour_val[3]; //stores the band value

#define nItems (sizeof item_list/sizeof *item_list)
//function prototyps
int srchItems (char *ccode); //a search for index values
char *strcpy2lower (char *dest, char *src); //converts to lower case
int scmp (char *a, char *b); //simple string comarison
char *sepnumber (char *s, long val);
int invalid (char answer[3][10]);
//main function
int main(int argc, char const *argv[])
{
    int i; // counter 
    char status = 'Y';// Keeps the program running when user inputs 'Y'
    long resistor_value = 0; //Total resistance
    int r, err, mult; //holds the significant figure, Error, Multiplier
    char resistor_value_string[20] = "";//formatted output
    while (status == 'Y') //The program runs under this
    {
        //print the question to the user
        printf("Enter the colours of the resistor's three bands,\nbeginning with the band nearest to the end.\nType the coloues in lowercase letters only, NO CAPS.\n");
        for (i = 0; i < MINC; ++i)
        {
            printf("Band %d => ", i + 1); // print headers for each band
            scanf(" %s", &answer[i]);  // get the user input
        }
        for (i = 0; i < MINC - 1; ++i) //converts colours into index
        {
            if ((r = srchItems (answer[i])) > -1)
            {
                // from significant figure
                resistor_value = (resistor_value * 10) + r;
            }
            else
            {
                invalid(answer);
                err = 2; 

            }
        }
        if (err > 1)
        {
            printf("Do you want to decode anothe resistor (Y/N)?\n");
            scanf (" %c", &status);
            if (status == 'Y');
            else break; 
        }
        else
        {
            mult = srchItems (answer[i]);       // get multiplier index
            resistor_value *= multiplier[mult]; // Calculate final value

            sepnumber (resistor_value_string, resistor_value);
            printf("Resistor value: ");
            /*for (int i = 0; i < (strlen(resistor_value_string) ); ++i)
            {
                printf("%c", resistor_value_string[i]);
            }
            */
            puts (resistor_value_string);   
            //printf(" -ohm\n");
            //memset (resistor_value_string, 0, 50);
            printf("Do you want to decode anothe resistor (Y/N)?\n");
            scanf (" %c", &status);
            if (status == 'Y');
            else break;
            /*Debug 
            for (int i = 0; i < MINC; ++i)
            {
                printf("item_list[%d] = %s\n", i, answer[i]);
            }
            printf("Total resistance = %ld\n", resistor_value);
            //end of debug */
        }
    }
    return 0;
}

int srchItems (char *ccode)
{
    int i;
    char lccode [MAXCC] = "";
    strcpy2lower (lccode, ccode); // converts everything to lower case
    for (int i = 0; i < (int)nItems; ++i) 
        if (*lccode == *(item_list[i].name))
            if (!scmp(item_list[i].name, lccode))
                return i;
    return -1;
}

char *strcpy2lower (char *dest, char *src)
{
    if (!src || !dest) return NULL;
    char *d = dest;
    for (; *src; src++, d++)
        if ('A' <= *src && *src <= 'Z')
            *d = *src | (1 << 5);
        else
            *d = *src;
    *d = 0;
    return dest;
}

int scmp (char *a, char *b)
{
    if (!a && !b) return 0;
    if ( a && !b) return 1;
    if (!a &&  b) return -1;

    for (; *a && *b && *a == *b; a++, b++) {}

    return *a - *b;
}


/** separate long value every 3rd char into 's' */
char *sepnumber (char *s, long val)
{
    char numstr[3 * MAXCC] = "";
    char *p = numstr;
    size_t idx = 0, len = 0;

    sprintf (numstr, "%ld", val);
    for (; *p; p++) {}
    len = p - numstr;
    p = s + 3 * MAXCC - 2;

    while (len--) {
        if (idx++ == 3) {
            idx = 1;
            *p-- = ' ';
        }
        *p = numstr[len];
        if (len) p--;
    }
    for (idx = 0; *p; p++, idx++) s[idx] = *p; /* copy to s */
    s[idx] = *p;    /* nul-terminate */
    return s;
}

int invalid (char answer[3][10])
{
    int r, counter = 0, incorrect[3], i;

    for (i = 0; i < MINC; ++i)
    {
        if ((r = srchItems (answer[i])) == -1)
        {
            incorrect[i] = r;
            counter++;
        }
    }
    if (counter == 1)
    {
        printf("%s","Invalid colour: " );
        printf("%s ", answer[i]);
        printf("\n");
    }
    i = 0;
}

This rev works well for the first loop, but it calculates the wrong resistor value on the second loop onwards. It will print the invalid entries with a little difficulty! After an invalid colour is inputted the program will not calculate any resistor values.

out put examples:

$ ./RQ1.exe
Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Type the coloues in lowercase letters only, NO CAPS.
Band 1 => red
Band 2 => orange
Band 3 => green
Resistor value: 2 300 000
Do you want to decode anothe resistor (Y/N)?
Y
Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Type the coloues in lowercase letters only, NO CAPS.
Band 1 => green
Band 2 => black
Band 3 => yellow
Resistor value: -2 101 970 656
Do you want to decode anothe resistor (Y/N)?
Y
Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Type the coloues in lowercase letters only, NO CAPS.
Band 1 => read
Band 2 => gren
Band 3 => blu
Do you want to decode anothe resistor (Y/N)?
Y
Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Type the coloues in lowercase letters only, NO CAPS.
Band 1 => red
Band 2 => orange
Band 3 => green
Do you want to decode anothe resistor (Y/N)?
N

Final Rev,

I think this is it:) beside the fact that it still has problem displaying the invalid inputs.

A really big tanks to David C. Rankin for helping out so much.

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

#define nItems (sizeof item_list/sizeof *item_list)

char status = 'Y'; 
//
enum {MINC = 3, MAXCC = 10};
// resister bands
enum resistor_band_items {BLACK, BROWN, RED, ORANGE, YELLOW, GREEN,
                                 BLUE, VIOLET, GRAY, WHITE, UNKNOWN};
struct items
 {
    char *name;
    enum resistor_band_items id;
 } item_list[] = {
    {"black", BLACK},
    {"brown", BROWN},
    {"red", RED},
    {"orange", ORANGE},
    {"yellow", YELLOW},
    {"green", GREEN},
    {"blue", BLUE},
    {"violet", VIOLET},
    {"gray", GRAY},
    {"white", WHITE}
};
unsigned int multiplier[] = {1, 10, 100, 1000, 10000, 100000, 1000000,
     10000000, 100000000, 1000000000};

int srchItems (char *ccode); //a search for index values
char *strcpy2lower (char *dest, char *src); //converts to lower case
int scmp (char *a, char *b); //simple string comarison
char *sepnumber (char *s, long val); //puts space every 3rd digit

int main(void)
{
    int i, error = 0, mult;
    char input[MINC][MAXCC]; //user input
    char invalid[MINC][MAXCC]; // invalid enteries
    int colour_val[MINC]; //stores the band value
    long total_resistance = 0; 
    char resistor_value_string[20] = "";//formatted output
    do
    {
    //prompt user 
    printf("%s\n%s\n%s\n",
        "Enter the colours of the resistor's three bands,",
        "beginning with the band nearest to the end.",
        "Type the colours in lowercase letters only, NO CAPS.");

    for (i = 0; i < MINC; ++i)
    {
        printf("Band %d => ", i + 1); // print headers for each band
        scanf(" %s", &input[i]);  // get the user input
        // converts user input to index of colours
        colour_val[i] = srchItems(input[i]); 
    }       
    for (i = 0; i < MINC; ++i)
    {
        if (colour_val[i] == -1)
        {
            strcpy(invalid[i], input[i]);
            error++;
        }
    }
    if (error > 0)
    {
        if (error == 1)
        {
            printf("Invalid colour: %s\n", invalid[0]);
        }
        else if (error == 2)
        {
            printf("Invalid colours: %s, %s\n", invalid[0], invalid[1]);
        }
        else 
        {
            printf("Invalid colours: %s, %s, %s\n",
             invalid[0], invalid[1], invalid[2]);
        }
    }
    else
    {
        //
        for (i = 0; i < MINC - 1; ++i)
        {
            total_resistance = (total_resistance * 10) + colour_val[i];
        }
        mult = colour_val[2];
        total_resistance *= multiplier[mult];
        sepnumber (resistor_value_string, total_resistance);

        printf("Resistance value: %s -Ohms\n", resistor_value_string);
//debug
        for (i = 0; i < MINC; ++i)
        {
            //printf("Input ==> %s\t", input[i]);
            //printf("index ==> %d\n", colour_val[i]);
        }
//end debug
    }
    error = 0;
    total_resistance = 0;
    for (i = 0; i < MINC; ++i)
    {
        colour_val[i] = 0;
    }
    //ask user if they want to continue
    printf("Do you want to decode another resistor?\n");
    scanf(" %c", &status);


    if (status == 'Y');
    else break;

    } while (status == 'Y');



    return 0;
}

int srchItems (char *ccode)
{
    int i;
    char lccode [MAXCC] = "";
    strcpy2lower (lccode, ccode); // converts everything to lower case
    for (int i = 0; i < (int)nItems; ++i) 
        if (*lccode == *(item_list[i].name))
            if (!scmp(item_list[i].name, lccode))
                return i;
    return -1;
}

char *strcpy2lower (char *dest, char *src)
{
    if (!src || !dest) return NULL;
    char *d = dest;
    for (; *src; src++, d++)
        if ('A' <= *src && *src <= 'Z')
            *d = *src | (1 << 5);
        else
            *d = *src;
    *d = 0;
    return dest;
}

int scmp (char *a, char *b)
{
    if (!a && !b) return 0;
    if ( a && !b) return 1;
    if (!a &&  b) return -1;

    for (; *a && *b && *a == *b; a++, b++) {}

    return *a - *b;
}

/** separate long value every 3rd char into 's' */
char *sepnumber (char *s, long val)
{
    char numstr[3 * MAXCC] = "";
    char *p = numstr;
    size_t idx = 0, len = 0;

    sprintf (numstr, "%ld", val);
    for (; *p; p++) {}
    len = p - numstr;
//printf("%d\n", len);
    p = s + 3 * MAXCC - 2;

    while (len--) {
        if (idx++ == 3) {
            idx = 1;
            *p-- = ' ';
        }
        *p = numstr[len];
        if (len) p--;
    }
    for (idx = 0; *p; p++, idx++) s[idx] = *p; /* copy to s */
    s[idx] = *p;    /* nul-terminate */
    return s;
}

Output example

$ ./Q1_token.exe
Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Type the colours in lowercase letters only, NO CAPS.
Band 1 => green
Band 2 => black
Band 3 => yellow
Resistance value: 500 000 -Ohms
Do you want to decode another resistor?
Y
Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Type the colours in lowercase letters only, NO CAPS.
Band 1 => red
Band 2 => orange
Band 3 => green
Resistance value: 2 300 000 -Ohms
Do you want to decode another resistor?
Y
Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Type the coloues in lowercase letters only, NO CAPS.
Band 1 => pink
Band 2 => silver
Band 3 => red
Invalid colours: pink, silver
Do you want to decode another resistor?
Y
Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Type the colours in lowercase letters only, NO CAPS.
Band 1 => vilot
Band 2 => brown
Band 3 => read
Invalid colours: vilot, silver
Do you want to decode another resistor?
N

解决方案

Your code for determining the significant figures in your resistor value is quite a bit more complex than needed. Since you declare the global array of struct item_list, all you need to do to form the significant figure is to use item_list as a lookup-table to find the index for the band-color entered. For each subsequent color (2nd [and 3rd for 5-band]), you simply multiply the current resistor value by 10 before adding the index.

For example with the item_list index variable r and the resistor value rval (including your check for an invalid color), your code could be reduced to:

int multiplier[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 };
...
    int err = 0, i, mult, r;
    long rval = 0;

    printf ("\ncolor bands determining significant figures:\n\n");
    for (i = 1; i < argc - 1; i++) { /* convert colors to index */
        if ((r = srchitems (argv[i])) != -1) {
            rval = rval * 10 + r;    /* form significant figure */
            prnitem (r);
        }
        else {
            fprintf (stderr, "error: invalid color '%s'\n", argv[i]);
            err = 1;
        }
    }
    if (err) return 1;
    mult = srchitems (argv[i]);     /* get multiplier index  */
    rval *= multiplier[mult];       /* calculare final value */
    printf ("\nmultiplier:\n\n");
    prnitem (mult);
    printf ("\nresistor value : %ld -ohms\n\n", rval);

    return 0;

Above your srchitems function simply returns the index in item_list given a color (entered as arguments to the program, e.g. argv[1], argv[2], ...) You can write a simple srchitems that converts all input to lowercase before preforming the lookup as:

/** search item_list for color code 'ccode', return index
 *  returns array index on success, -1 otherwise.
 */
int srchitems (char *ccode)
{
    int i;
    char lccode[MAXCC] = "";       /* array to hold lowercase color */

    strcpy2lower (lccode, ccode);  /* convert string to lowercase */

    for (i = 0; i < (int)nitems; i++)    /* lookup index */
        if (*lccode == *(item_list[i].name))
            if (!scmp (item_list[i].name, lccode))
                return i;

    return -1;   /* return -1 on error */
}

If you put the remaining pieces of the puzzle together, you could do something similar to the following. I leave it to you to format the output as needed. You can replace the simple string comparison function scmp with strcmp (and include string.h) Let me know if you have any questions.

#include <stdio.h>

/* resister bands */
enum resistor_band_items { BLACK, BROWN, RED, ORANGE, YELLOW, GREEN, 
                        BLUE, VIOLET, GRAY, WHITE, UNKNOWN };
/* constants for min/max color arguments and max color chars */
enum { MINC = 3, MAXC = 4, MAXCC = 8 };

struct items    /* could be simple array of strings */
{
    char *name;
    enum resistor_band_items id;
} item_list[] = {
    {"black", BLACK},
    {"brown", BROWN},
    {"red", RED},
    {"orange", ORANGE},
    {"yellow", YELLOW},
    {"green", GREEN},
    {"blue", BLUE},
    {"violet", VIOLET},
    {"gray", GRAY},
    {"white", WHITE}
};
/* resistor multiplier values */
int multiplier[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 };

#define nitems (sizeof item_list/sizeof *item_list)

int srchitems (char *ccode);
char *strcpy2lower (char *dest, char *src);
int scmp (char *a, char *b);
void prnitem (int i);

int main (int argc, char **argv) {

    if (argc < MAXC || MAXC + 1 < argc) { /* check 3 or 4 arguments */
        fprintf (stderr, "error: invalid input, usage: %s c1 c2 c3 [c4]\n"
                         "usage: enter color codes for 4 or 5-band resistor\n"
                         "       (tolerance ignored, enter 4 colors max)\n",
                        argv[0]);
        return 1;
    }

    int err = 0, i, mult, r;
    long rval = 0;

    printf ("\ncolor bands determining significant figures:\n\n");
    for (i = 1; i < argc - 1; i++) { /* convert colors to index */
        if ((r = srchitems (argv[i])) != -1) {
            rval = rval * 10 + r;    /* form significant figure */
            prnitem (r);
        }
        else {
            fprintf (stderr, "error: invalid color '%s'\n", argv[i]);
            err = 1;
        }
    }
    if (err) return 1;
    mult = srchitems (argv[i]);     /* get multiplier index  */
    rval *= multiplier[mult];       /* calculare final value */
    printf ("\nmultiplier:\n\n");
    prnitem (mult);
    printf ("\nresistor value : %ld -ohms\n\n", rval);

    return 0;
}

/** search item_list for color code 'ccode', return index
 *  returns array index on success, -1 otherwise.
 */
int srchitems (char *ccode)
{
    int i;
    char lccode[MAXCC] = "";

    strcpy2lower (lccode, ccode);

    for (i = 0; i < (int)nitems; i++)
        if (*lccode == *(item_list[i].name))
            if (!scmp (item_list[i].name, lccode))
                return i;

    return -1;
}

/** copy and convert string to lowercase.
 *  returns copy of string with all chars converted to lowercase.
 *  ('dest' must be of sufficient size of hold 'src')
 */
char *strcpy2lower (char *dest, char *src)
{
    if (!src || !dest) return NULL;

    char *d = dest;

    for (; *src; src++, d++)
        if ('A' <= *src && *src <= 'Z')
            *d = *src | (1 << 5);
        else
            *d = *src;

    *d = 0;

    return dest;
}

/** simple string comparison (like strcmp) */
int scmp (char *a, char *b)
{
    if (!a && !b) return 0;
    if ( a && !b) return 1;
    if (!a &&  b) return -1;

    for (; *a && *b && *a == *b; a++, b++) {}

    return *a - *b;
}

void prnitem (int i)
{
    printf (" item_list[%d]  name: %-6s  id: %d\n", 
            i, item_list[i].name, item_list[i].id);
}

Example Use/Output

Valid resistor colors (uppercase or lowercase characters are fine)

$ ./bin/resistor green blue yellow

color bands determining significant figures:

 item_list[5]  name: green   id: 5
 item_list[6]  name: blue    id: 6

multiplier:

 item_list[4]  name: yellow  id: 4

resistor value : 560000 -ohms


$ ./bin/resistor Red Orange Violet Black

color bands determining significant figures:

 item_list[2]  name: red     id: 2
 item_list[3]  name: orange  id: 3
 item_list[7]  name: violet  id: 7

multiplier:

 item_list[0]  name: black   id: 0

resistor value : 237 -ohms

Invalid colors generate individual errors:

$ ./bin/resistor pink silver green

color bands determining significant figures:

error: invalid color 'pink'
error: invalid color 'silver'

Splitting Number Every 3rd char

Rather than a fairly complicated approach where you are relying on numeric calculations to test/separate your number, why not just convert your number to a string (without decimal places) and then simply work backwards from the end copying characters to a new string and add a space every 3rd character? It makes things a whole lot easier. (even though you are using a double for some unheard-of-reason -- assuming you will ultimately incorporate tolerance) It really makes no difference with this approach. Give the following a try:

void print_number (double number)
{
    char numstr[3 * MAXCC] = "", sepstr[3 * MAXCC] = "";
    char *p = NULL;
    size_t idx = 0, len = 0;

    sprintf (numstr, "%.0lf", number);  /* write double to string */
    len = strlen (numstr);              /* get length */
    p = sepstr + 3 * MAXCC - 2;         /* set p at last char in sepstr */

    while (len--) {         /* for each char in numstr */
        if (idx++ == 3) {   /* if 3 characters copied  */
            idx = 1;        /* reset index */
            *p-- = ' ';     /* write a space in sepstr */
        }
        *p = numstr[len];   /* write char in sepstr    */
        if (len) p--;       /* decrement p if not at 0 */
    }

    printf ("p : '%s'\n", p);  /* print the separate value */
}

note, you can simply pass a character array to print_number and copy p to the array if you want to make the array available back in main for formatting reasons (you can even change print_number to return char * in that case.) Let me know if it works. If you can't do it that way, then I'll work through your numeric logic, but that will take aspirin and will probably be in the morning :)

Example print_number Output

           5 => '5'
          55 => '55'
         555 => '555'
        5555 => '5 555'
       55555 => '55 555'
      555555 => '555 555'
     5555555 => '5 555 555'
    55555555 => '55 555 555'
   555555555 => '555 555 555'

Example of Actual Implementation

Here is the way I implemented it into my code. Essentially, you just move sepstr declaration/initialization into main and then pass it as an array to your print_number (my sepnumber below).

char *sepnumber (char *s, long val);
...
    long rval = 0;
    char rstr[3 * MAXCC] = "";
    ...
    printf ("\nresistor value : %s -ohms\n\n", sepnumber (rstr, rval));

    return 0;
}
...
/** separate long value every 3rd char into 's' */
char *sepnumber (char *s, long val)
{
    char numstr[3 * MAXCC] = "";
    char *p = numstr;
    size_t idx = 0, len = 0;

    sprintf (numstr, "%ld", val);
    for (; *p; p++) {}
    len = p - numstr;
    p = s + 3 * MAXCC - 2;

    while (len--) {
        if (idx++ == 3) {
            idx = 1;
            *p-- = ' ';
        }
        *p = numstr[len];
        if (len) p--;
    }
    for (idx = 0; *p; p++, idx++) s[idx] = *p; /* copy to s */
    s[idx] = *p;    /* nul-terminate */

    return s;
}

Example/Output

$ ./bin/resistor green blue yellow

color bands determining significant figures:

 item_list[5]  name: green   id: 5
 item_list[6]  name: blue    id: 6

multiplier:

 item_list[4]  name: yellow  id: 4

resistor value : 560 000 -ohms


$ ./bin/resistor Red Orange Violet Brown

color bands determining significant figures:

 item_list[2]  name: red     id: 2
 item_list[3]  name: orange  id: 3
 item_list[7]  name: violet  id: 7

multiplier:

 item_list[1]  name: brown   id: 1

resistor value : 2 370 -ohms

Reinitialize Values When Looping for Input

Given your description of the problem, I strongly suspect the issue you are having is due to not resetting/reinitializing rval = 0; (your resistor_value) at the end of each loop (or some similar value). Always check which values may be additive, etc. and remember to reset those values at the beginning of each loop. Another way to handle this in most cases is to declare the variables within the scope of the loop so that they are automatically reinitialized each iteration.

Using block scope for the loop, your main should be similar to the following:

int main (void) {

    for (;;) {                      /* loop for input */
        int err = 0, i, mult, r;    /* variables have block scope only */
        long rval = 0;
        char ccode[MAXCC] = "", rstr[3 * MAXCC] = "";

        printf ("\nEnter the colours of the resistor's three bands,\n"
                "beginning with the band nearest to the end.\n");
        for (i = 0; i < MINC; i++) { /* convert colors to index */
            printf ("Band %d => ", i + 1);
            if (scanf (" %7s", ccode) != 1) {
                fprintf (stderr, "error: invalid input or EOF.\n");
                return 1;
            }
            if ((r = srchitems (ccode)) != -1) {
                if (i < 2) {
                    rval = rval * 10 + r;    /* form significant figure */
                }
                else {
                    mult = srchitems (ccode);  /* get multiplier index  */
                    rval *= multiplier[mult];  /* calculare final value */
                }
            }
            else {
                fprintf (stderr, "error: invalid color '%s'\n", ccode);
                err = 1;
            }
        }
        if (err) return 1;
        printf ("Resistor value : %s -ohms\n", sepnumber (rstr, rval));
        printf ("\nDo you want to decode another resistor (y/n)? ");
        if (scanf (" %7s", ccode) != 1) {
            fprintf (stderr, "error: invalid input or EOF.\n");
            return 1;
        }
        if (*ccode != 'y' && *ccode != 'Y') break;
    }

    return 0;
}

Example Use/Output

$ ./bin/resistor2

Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Band 1 => green
Band 2 => blue
Band 3 => yellow
Resistor value : 560 000 -ohms

Do you want to decode another resistor (y/n)? y

Enter the colours of the resistor's three bands,
beginning with the band nearest to the end.
Band 1 => red
Band 2 => orange
Band 3 => orange
Resistor value : 23 000 -ohms

Do you want to decode another resistor (y/n)? n

I suspect you can find your error with this hint.

这篇关于解决 - 其色带作为输入计算的电阻值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆