C 以其色带作为输入计算电阻值
我正试图开发一个C程序,通过输入电阻器上标记的色带来计算电阻器的值 忽略电阻公差 e、 gC 以其色带作为输入计算电阻值,c,struct,c-strings,C,Struct,C Strings,我正试图开发一个C程序,通过输入电阻器上标记的色带来计算电阻器的值 忽略电阻公差 e、 g 显示电阻值的所需格式。例如,如果电阻值为“500000-ohms”,则要求格式为 “500000欧姆”。必须在每3位数字之间留出一个空格 显示单一无效颜色。例如,如果输入“棕色”、“vilet”和“红色”作为电阻器颜色,则程序 生成以下消息:无效颜色:仅限此处 “vilet”是唯一无效的颜色 显示多个无效颜色。例如,如果输入“粉色”、“银色”和“红色”作为电阻器颜色,则程序 应在单行中生成以下消息: 无效
无效颜色:仅限此处
“vilet”是唯一无效的颜色
无效颜色:粉色、银色
这里有两种无效颜色“粉色”和“银色”
“银色”。注意“颜色”#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);
}
此转速在第一个回路中运行良好,但在第二个回路上计算错误的电阻值。
它将打印无效的条目,有点困难!
输入无效颜色后,程序将不会计算任何电阻值
举例说明:
最终版本,
我认为是这样:)除了显示无效输入仍然存在问题之外
一个非常大的坦克来感谢你这么多的帮助
#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;
}
我觉得你打印号码的代码太复杂了。请看以下代码:
int num = 2345666;
printf("%d\n", num);
int triad[10];
int i = 0;
do
{
triad[i++] = num % 1000;
num /= 1000;
}while(num);
for(i--; i >= 0; i--)
printf("%d ", triad[i]);
printf("\n");
它又快又脏。擦亮它。确定电阻值中有效数字的代码比需要的复杂得多。由于您声明了struct
item_list
的全局数组,因此要形成有效数字,只需使用item_list
作为查找表来查找输入的色带颜色的索引。对于每个后续颜色(第二种[第三种为5波段]),在添加索引之前,只需将当前电阻值乘以10
例如,使用item_list
索引变量r
和电阻值rval
(包括检查无效颜色),代码可以减少为:
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;
如果你把拼图的剩余部分放在一起,你可以做如下类似的事情。我让您根据需要格式化输出。您可以将简单的字符串比较函数scmp
替换为strcmp
(包括string.h
),如果您有任何问题,请告诉我
#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);
}
无效颜色会生成单个错误:
$ ./bin/resistor pink silver green
color bands determining significant figures:
error: invalid color 'pink'
error: invalid color 'silver'
每三个字符拆分一个数字
与其采用一种相当复杂的方法,即依靠数值计算来测试/分离数字,不如将数字
转换为字符串(不带小数点),然后简单地从末尾向后复制字符到新字符串,并每隔三个字符添加一个空格
?这让事情变得简单多了。(即使您出于某种前所未闻的原因使用了double
——假设您最终会合并公差),但这种方法实际上没有什么区别。尝试以下方法:
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 */
}
注意,如果出于格式化原因,您想让数组回到main
中,您只需将字符数组传递给print\u number
,然后将p
复制到数组中(在这种情况下,您甚至可以更改print\u number
以返回char*
),让我知道它是否有效。如果你不能这样做,那么我将研究你的数字逻辑,但这需要阿斯匹林,可能会在早上:)
示例打印编号
输出
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'
$ ./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
$ ./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
实际实施示例
下面是我在代码中实现它的方法。基本上,您只需将sepstr
声明/初始化移动到main
中,然后将其作为数组传递给您的print\u number
(下面是mysepnumber
)
示例/输出
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'
$ ./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
$ ./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
循环输入时重新初始化值
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'
$ ./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
$ ./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
根据您对问题的描述,我强烈怀疑您遇到的问题是由于未重置/重新初始化rval=0
(您的电阻值
)位于每个回路的末端(或一些类似值)。始终检查哪些值可能是加法等,并记住在每个循环开始时重置这些值。在大多数情况下,另一种处理方法是在循环范围内声明变量,以便在每次迭代中自动重新初始化变量
使用循环的块范围,您的main
应该类似于以下内容:
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;
}
我怀疑您可以通过此提示找到错误。
状态预计为单个字符。因此,将其定义为charstatus='Y'
。您将其定义为char status[1]=“Y”
,这是不正确的,因为您没有考虑'\0'
字符。@CinCout,我将其作为单个字符,但我的编译器出于某些原因不喜欢它!它现在与状态[1]=“Y”一起工作!我正在传递一个双精度到“print_number”函数<代码>三元组[i++]=num%1000
将生成一个错误,将您的double拆分为两部分(整数和分数),并将它们打印为整数。会更简单的。谢谢你的帮助。程序应该遵循精确的格式(这并不难理解)
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;
}
$ ./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