英文:
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] = {
{"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;
}
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] = {
{"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;
}
答案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 <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'; // remove the newline if any
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("unknown unit\n");
}
printf("unexpected end of file, aborting\n");
exit(1);
}
int main(void) {
int from, to;
double val;
printf("Enter what you want to convert from: ");
from = get_unit();
printf("Enter what you want to convert to: ");
to = get_unit();
printf("Enter the numerical value of conversion: ");
if (scanf("%lf", &val) == 1) {
double result = val * units[from].factor / units[to].factor;
printf("Answer is %g %s\n", 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
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[] = {
{ "millimeters", "mm", 0.001 },
{ "centermeters", "cm", 0.01 },
{ "meters", "m", 1.0 },
{ "kilometers", "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, "Unrecognized unit: %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("answer is %f %s\n",
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论