计算电阻值及其色带作为输入

时间:2016-05-04 05:53:31

标签: c struct c-strings

我正在尝试开发一个C程序,通过输入电阻上标记的色带来计算电阻值。

忽略电阻容差。

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. 显示电阻值的所需格式。例如,如果电阻值为" 500000 -ohms",则格式必须为   " 500 000 -ohms"。每3个数字之间必须放一个空格。
  2.   
  3. 显示单个无效颜色。例如,如果' brown',' vilet'和' red'作为电阻器颜色,程序输入   生成以下消息:Invalid colour: vilet仅限此处   ' vilet'是唯一无效的颜色。
  4.   
  5. 显示多种无效颜色。例如,如果粉红色','银'和'红'作为电阻器颜色,程序输入   应该在一行中生成以下消息:   Invalid colours: pink, silver这是两种无效的颜色'粉红色'和   '银&#39 ;.请注意'颜色'。
  6.   

现在我很难获得总阻力格式(#1)。对于#2& #3当且仅当第一个输入(波段1)无效时,程序才会运行。如果第一个频段或第三个频段无效且第一个频段无效,程序将停止执行。

以下是我一直致力于的代码:

#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);
}

我已经编辑了print_number函数,因此每隔3位打印一个空格。 (适用于大多数组合)

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

这里是来自答案的修改后的代码。 我没有使用argcargv的原因是客户端有一个需要遵循的限制格式(这让我很生气!)

这是代码:

    //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;
}

此转速适用于第一个循环,但它会在第二个循环上计算错误的电阻值。 它将打印无效的条目有点困难! 输入无效颜色后,程序将不计算任何电阻值。

输出示例:

$ ./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

最终版本,

我认为就是这样:)除了显示无效输入时仍有问题。

David C. Rankin帮助这么多的坦克。

#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;
}

输出示例

$ ./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

2 个答案:

答案 0 :(得分:2)

用于确定电阻值中有效数字的代码比需要的要复杂得多。由于您声明了struct item_list的全局数组,因此您需要做的只是使用item_list作为查找表来查找输入的band-color的索引。对于每个后续颜色(第2个[和5个波段的第3个]),您只需在添加索引之前将当前电阻值乘以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;

srchitems函数之上只返回{​​{1}}中给定颜色的索引(作为程序的参数输入,例如item_listargv[1],...)可以编写一个简单的argv[2],在将查找执行为:

之前将所有输入转换为小写
srchitems

如果你把拼图的剩余部分放在一起,你可以做类似以下的事情。我留给你根据需要格式化输出。您可以将简单字符串比较函数/** 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 */ } 替换为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 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

分裂号码每隔3个字符

与其依赖数值计算来测试/分离数字的相当复杂的方法,为什么不将$ ./bin/resistor pink silver green color bands determining significant figures: error: invalid color 'pink' error: invalid color 'silver' 转换为字符串(不带小数位),然后简单地从末尾复制向后工作将字符添加到新字符串并每隔第3个字符添加一个number?它使事情变得更加容易。 (即使你使用space一些闻所未闻的假设 - 假设你最终会纳入容忍度)这对这种方法没有任何影响。试试以下内容:

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 */ } ,然后将print_number复制到数组中,如果您想在p中使数组可用出于格式原因(在这种情况下,您甚至可以将main更改为返回print_number。)如果有效,请告诉我。如果你不能这样做,那么我将通过你的数字逻辑,但这将需要阿司匹林,可能会在早上char *

示例:)输出

print_number

实际实施示例

这是我在代码中实现它的方式。基本上,您只需将 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' 声明/初始化移至sepstr,然后将其作为数组传递到main(我的print_number下方)。

sepnumber

示例/输出

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;
}

循环输入时重新初始化值

鉴于您对问题的描述,我强烈怀疑您遇到的问题是由于未在每个循环结束时重置/重新初始化$ ./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 (您的rval = 0;)(或某些类似的值) 。始终检查哪些值可能是加性等,并记住在每个循环开始时重置这些值。在大多数情况下处理这种情况的另一种方法是在循环范围内声明变量,以便在每次迭代时自动重新初始化。

使用块范围进行循环,您的resistor_value应与以下内容类似:

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;
}

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

答案 1 :(得分:0)

我认为您的数字打印代码太复杂了。请看下面的代码:

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");

这很快又脏。擦亮它。