在C语言中,有一种方法可以比较多个字符串吗?[我通过fgets()输入它们]

huangapple go评论73阅读模式
英文:

Is there a way to compare multiple strings in C? [ I input them through fgets() ]

问题

int Distance() {
    char from[40], to[40];
    double val;
    double result;

    printf("输入要转换的单位:");
    fflush(stdin);
    fgets(from, 40, stdin);

    printf("输入要转换到的单位:\n");
    fflush(stdin);
    fgets(to, 40, stdin);

    printf("输入转换的数值:\n");
    scanf("%lf", &val);

    (strcmp(from, "cm") == 0 && strcmp(to, "mm") == 0) ? printf("答案是 %lf 毫米", val / 10) : 
    (strcmp(from, "mm") == 0 && strcmp(to, "cm") == 0) ? printf("答案是 %lf 厘米", val * 10) :
    (strcmp(from, "cm") == 0 && strcmp(to, "km") == 0) ? printf("答案是 %lf 千米", val / 100000) : 
    (strcmp(from, "km") == 0 && strcmp(to, "cm") == 0) ? printf("答案是 %lf 厘米", val * 100000) : 
    (strcmp(from, "mm") == 0 && strcmp(to, "km") == 0) ? printf("答案是 %lf 千米", val / 1000000) : 
    (strcmp(from, "km") == 0 && strcmp(to, "mm") == 0) ? printf("答案是 %lf 毫米", val * 1000000) : 
    printf("请输入有效的转换单位");
}
英文:
int Distance() {
    char from[40], to[40];
    double val;
    double result;

    printf("Enter what you want to convert from: ");
    fflush(stdin);
    fgets(from, 40, stdin);

    printf("Enter what you want to convert to: \n");
    fflush(stdin);
    fgets(to, 40, stdin);

    printf("Enter the numerical value of conversion: \n");
    scanf("%lf", &val);

    (strcmp(from, "cm") == 0 && strcmp(to, "mm") == 0) ? printf("Answer is %lf MilliMeters", val / 10) : 
    (strcmp(from, "mm") == 0 && strcmp(to, "cm") == 0) ? printf("Answer is %lf CentiMeters", val * 10) :
    (strcmp(from, "cm") == 0 && strcmp(to, "km") == 0) ? printf("Answer if %lf KiloMeters", val * 100000) : 
    (strcmp(from, "km") == 0 && strcmp(to, "cm") == 0) ? printf("Answer is %lf CentiMeters", val / 100000) : 
    (strcmp(from, "mm") == 0 && strcmp(to, "km") == 0) ? printf("Anser is %lf KiloMeters", val  * 1000000) : 
    (strcmp(from, "km") == 0 && strcmp(to, "mm") == 0) ? printf("Answer is %lf  MilliMeters", val / 1000000) : 
    printf("Please enter valid conversion units");
}

I am trying to make a unit converter. So I have made different functions for different conversions - like int distance(),
int time() and so on.

In my function to calculate distances, I used fgets() to get multi-char inputs like 'cm', 'mm, etc.
What i am trying to achieve is
If value of fgets in char from is "any string" and fgets in char to is "any other string": print result whose formula is -----(something)

It doesn't compute the result and directly jumps to the final printf("Please enter valid conversion units")

I am still learning at a beginner level, it could be a minor mistake, Please help.

答案1

得分: 1

Here's the translated code without the comments:

const char* mapper[6][3] = {
    {"cm", "mm", "millimeters"},
    {"cm", "km", "kilometers"},
    {"mm", "cm", "centimeters"},
    {"mm", "km", "kilometers"},
    {"km", "cm", "centimeters"},
    {"km", "mm", "millimeters"},
};

for (int i = 0; i < 6; i++) {
    if (strcmp(from, mapper[i][0]) != 0) continue;
    if (strcmp(to, mapper[i][1]) != 0) continue;
    printf("answer is %lf, %s", val, mapper[i][2]);
    break;
}

And here's the updated code with conversion factors:

const char* mapper[6][4] = {
    {"cm", "mm", "millimeters", "10"},
    {"cm", "km", "kilometers", "0.00001"},
    {"mm", "cm", "centimeters", "0.1"},
    {"mm", "km", "kilometers", "0.000001"},
    {"km", "cm", "centimeters", "100000"},
    {"km", "mm", "millimeters", "1000000"},
};

for (int i = 0; i < 6; i++) {
    if (strcmp(from, mapper[i][0]) != 0) continue;
    if (strcmp(to, mapper[i][1]) != 0) continue;
    printf("answer is %lf, %s", val * atof(mapper[i][3]), mapper[i][2]);
    break;
}
英文:
const char* mapper[6][3] = {
	{&quot;cm&quot;, &quot;mm&quot;, &quot;millimeters&quot;},
	{&quot;cm&quot;, &quot;km&quot;, &quot;kilometers&quot;},
	{&quot;mm&quot;, &quot;cm&quot;, &quot;centimeters&quot;},
	{&quot;mm&quot;, &quot;km&quot;, &quot;kilometers&quot;},
	{&quot;km&quot;, &quot;cm&quot;, &quot;centimeters&quot;},
	{&quot;km&quot;, &quot;mm&quot;, &quot;millimeters&quot;},
};

for(int i=0; i&lt;6; i++)
{
	if(strcmp[from, mapper[i][0]] != 0) continue;
	if(strcmp[to, mapper[i][1] != 0) continue;
	printf(&quot;answer is %lf, %s&quot;, val, mapper[i][2]);
	break;
}

You can declare standard and constant messages. then use that array to sequentially search for it. It is more clean.

Also use scanf cause it doesn't adds the newline character to input or if you really want to use fgets. Then just use buffer size of 3. For e.g.


char from[3];
fgets(from, 3, stdin);


EDIT:

And to perform conversion

const char* mapper[6][4] = {
	{&quot;cm&quot;, &quot;mm&quot;, &quot;millimeters&quot;, &quot;10&quot;},
	{&quot;cm&quot;, &quot;km&quot;, &quot;kilometers&quot;, &quot;0.00001&quot;},
	{&quot;mm&quot;, &quot;cm&quot;, &quot;centimeters&quot;, &quot;0.1&quot;},
	{&quot;mm&quot;, &quot;km&quot;, &quot;kilometers&quot;, &quot;0.000001&quot;},
	{&quot;km&quot;, &quot;cm&quot;, &quot;centimeters&quot;, &quot;100000&quot;},
	{&quot;km&quot;, &quot;mm&quot;, &quot;millimeters&quot;, &quot;1000000&quot;},
};

for(int i=0; i&lt;6; i++)
{
	if(strcmp[from, mapper[i][0]] != 0) continue;
	if(strcmp[to, mapper[i][1] != 0) continue;
	printf(&quot;answer is %lf, %s&quot;, val * atof(mapper[i][3]), mapper[i][2]);
	break;
}

答案2

得分: 1

代码中存在多个问题:

  • fgets() 存储目标数组末尾的换行符,因此与单位字符串的所有比较都会失败。
  • 您应该使用一个中间单位,以避免测试所有组合。

这是一个修改后的版本:

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

struct unit {
    double factor;
    const char *abbrev, *singular, *plural;
} const units[] = {
    { 1, "mm", "millimeter", "millimeters" },
    { 10, "cm", "centimeter", "centimeters" },
    { 100, "dm", "decimeter", "decimeters" },
    { 1000, "m", "meter", "meters" },
    { 10000, "dam", "decameter", "decameters" },
    { 100000, "hm", "hectometer", "hectometers" },
    { 1000000, "km", "kilometer", "kilometers" },
    { 25.4, "in", "inches", "inches" },
    { 304.8, "ft", "foot", "feet" },
    { 914.4, "yd", "yards", "yards" },
    { 201168, "fur", "furlong", "furlongs" },
    { 1609344, "mi", "mile", "miles" },
};

int get_unit(void) {
    char buf[40];
    while (fgets(buf, sizeof buf, stdin)) {
        buf[strcspn(buf, "\n")] = '\0';   // 移除换行符(如果有的话)
        for (int i = 0, n = sizeof(units) / sizeof(*units); i < n; i++) {
            if (!strcmp(buf, units[i].abbrev)
            ||  !strcmp(buf, units[i].singular)
            ||  !strcmp(buf, units[i].plural)) {
                return i;
            }
        }
        printf("未知单位\n");
    }
    printf("意外到达文件末尾,中止\n");
    exit(1);
}

int main(void) {
    int from, to;
    double val;

    printf("输入要进行转换的单位(从):");
    from = get_unit();

    printf("输入要进行转换的单位(到):");
    to = get_unit();

    printf("输入转换的数值:");
    if (scanf("%lf", &val) == 1) {
        double result = val * units[from].factor / units[to].factor;
        printf("答案是 %g %s\n", result, result == 1 ? units[to].singular : units[to].plural);
        return 0;
    }
    return 1;
}
英文:

There are multiple issues in the code:

  • fgets() stores the trailing newline at the end of the target array, so all comparisons with unit strings will fail.
  • you should use an intermediary unit to avoid having to test all combinations.

Here is a modified version:

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
struct unit {
double factor;
const char *abbrev, *singular, *plural;
} const units[] = {
{ 1, &quot;mm&quot;, &quot;millimeter&quot;, &quot;millimeters&quot; },
{ 10, &quot;cm&quot;, &quot;centimeter&quot;, &quot;centimeters&quot; },
{ 100, &quot;dm&quot;, &quot;decimeter&quot;, &quot;decimeters&quot; },
{ 1000, &quot;m&quot;, &quot;meter&quot;, &quot;meters&quot; },
{ 10000, &quot;dam&quot;, &quot;decameter&quot;, &quot;decameters&quot; },
{ 100000, &quot;hm&quot;, &quot;hectometer&quot;, &quot;hectometers&quot; },
{ 1000000, &quot;km&quot;, &quot;kilometer&quot;, &quot;kilometers&quot; },
{ 25.4, &quot;in&quot;, &quot;inches&quot;, &quot;inches&quot; },
{ 304.8, &quot;ft&quot;, &quot;foot&quot;, &quot;feet&quot; },
{ 914.4, &quot;yd&quot;, &quot;yards&quot;, &quot;yards&quot; },
{ 201168, &quot;fur&quot;, &quot;furlong&quot;, &quot;furlongs&quot; },
{ 1609344, &quot;mi&quot;, &quot;mile&quot;, &quot;miles&quot; },
};
int get_unit(void) {
char buf[40];
while (fgets(buf, sizeof buf, stdin)) {
buf[strcspn(buf, &quot;\n&quot;)] = &#39;\0&#39;;   // remove the newline if any
for (int i = 0, n = sizeof(units) / sizeof(*units); i &lt; n; i++) {
if (!strcmp(buf, units[i].abbrev)
||  !strcmp(buf, units[i].singular)
||  !strcmp(buf, units[i].plural)) {
return i;
}
}
printf(&quot;unknown unit\n&quot;);
}
printf(&quot;unexpected end of file, aborting\n&quot;);
exit(1);
}
int main(void) {
int from, to;
double val;
printf(&quot;Enter what you want to convert from: &quot;);
from = get_unit();
printf(&quot;Enter what you want to convert to: &quot;);
to = get_unit();
printf(&quot;Enter the numerical value of conversion: &quot;);
if (scanf(&quot;%lf&quot;, &amp;val) == 1) {
double result = val * units[from].factor / units[to].factor;
printf(&quot;Answer is %g %s\n&quot;, result, result == 1 ? units[to].singular : units[to].plural);
return 0;
}
return 1;
}

答案3

得分: 0

请参考以下翻译:

// 将每对单位的转换比率分为两步进行:首先将输入转换为米,然后从米转换为输出单位。

// 如果你有 N 种可能的单位,这种方法只需要 N 个转换比率,而分别处理每对单位需要 N^2 个。

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

struct Ratio {
    const char *name;
    const char *abbrev;
    double meters;
};

// 这实际上应该是一个哈希表,但一步一步来
struct Ratio ratios[] = {
    { "毫米", "mm", 0.001 },
    { "厘米", "cm", 0.01 },
    { "米", "m", 1.0 },
    { "千米", "km", 1000.0 },
};

size_t get_ratio(const char *unit) {
    const size_t N = sizeof(ratios) / sizeof(struct Ratio);
    for (size_t idx = 0; idx < N; idx++) {
        if (0 == strcmp(unit, ratios[idx].abbrev)) return idx; 
    }
    fprintf(stderr, "无法识别的单位:%s\n", unit);
    return SIZE_MAX;
}

void convert(const char *from_unit, const char *to_unit, double val) {
    size_t conv0 = get_ratio(from_unit);
    size_t conv1 = get_ratio(to_unit);
    if (SIZE_MAX == conv0 || SIZE_MAX == conv1) return;
    printf("答案是 %f %s\n",
        val * ratios[conv0].meters / ratios[conv1].meters,
        ratios[conv1].name);
}

请注意,这也正确处理了输入和输出单位相同时的情况。

英文:

Instead of having a conversion ratio for every pair of units, do it in two steps: first convert the input to meters, then convert from meters to the output unit.

If you have N possible units, this approach will only require N conversion ratios, whereas doing each pair separately requires N^2.

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;stdint.h&gt;
struct Ratio {
const char *name;
const char *abbrev;
double meters;
};
// This should really be a hash table, but one thing at a time
struct Ratio ratios[] = {
{ &quot;millimeters&quot;, &quot;mm&quot;, 0.001 },
{ &quot;centermeters&quot;, &quot;cm&quot;, 0.01 },
{ &quot;meters&quot;, &quot;m&quot;, 1.0 },
{ &quot;kilometers&quot;, &quot;km&quot;, 1000.0 },
};
size_t get_ratio(const char *unit) {
const size_t N = sizeof(ratios) / sizeof(struct Ratio);
for (size_t idx = 0; idx &lt; N; idx++) {
if (0 == strcmp(unit, ratios[idx].abbrev)) return idx; 
}
fprintf(stderr, &quot;Unrecognized unit: %s\n&quot;, unit);
return SIZE_MAX;
}
void convert(const char *from_unit, const char *to_unit, double val) {
size_t conv0 = get_ratio(from_unit);
size_t conv1 = get_ratio(to_unit);
if (SIZE_MAX == conv0 || SIZE_MAX == conv1) return;
printf(&quot;answer is %f %s\n&quot;,
val * ratios[conv0].meters / ratios[conv1].meters,
ratios[conv1].name);
}

Note that this also correctly handles the case where your input and output units are the same.

答案4

得分: 0

你可以使用哈希表并检查你的字符串是否包含在其中。你将能够找出哪个字符串是被选中的。在每个条目上,你还可以保存乘法因子,以便进行单位转换或者其他所需的信息。搜索速度很快(它与表中实际字符串数量无关),并且将非常高效。

英文:

You can use a hash table and check if your string is contained in it. You'll be able to get which of the strings is the one selected. On each entry you can save also the multiplication facto to do unit conversion or whatever information is required. Search is fast (it's independent of the actual number of strings in the table) and will be very efficient.

huangapple
  • 本文由 发表于 2023年7月6日 18:44:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76627995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定