我正在创建一个程序,用于检查将从起始机场到目的地机场的可能航空公司(这些信息都将由用户输入)。我有一个包含所有航空公司#及其相应机场的文件。例如,10A, LIM, LAX
具有航空公司编号(10A),起始机场(LIM)和目的地机场(LAX)。每行包含遵循航空公司#,原始机场(缩写)和目的地机场(缩写)格式的信息。
我将使C读取文件,它将使用fgets
函数读取每一行,直到它到达与起始机场和目的地机场相匹配的行。然后,它将返回航空公司号码。如果没有,那么计算机将打印出没有航空公司有该航班。由于每一行都将被视为一个字符串,该字符串将存储在我称为str[10000]
的字符数组中。我希望使用strcat
功能存储航空公司号码。我想做的是strcat(str[0], str[1])
,它会加入,例如我使用10A的示例是组合10(将存储在str [0]中)和A(将存储在str中) [1])。这种方法似乎不是出于某种原因而起作用。
我创建了函数void route(char *origin, char *destination, char *airline[])
来打印出航空公司号码,但我不知道如何使用该阵列并将它们存储到*airline[]
中。我还初始化为*airline[20]
因为可能有几家航空公司从用户指定的起点到目的地。
我只是想确保我最终可以使用strcmp
来比较用户为原始机场和目的地机场输入的内容,以便如果它与航空公司号码匹配则将报告。
请帮我处理字符串和数组。当我尝试编译并运行程序时,在进入原始机场和目的地机场后,我收到错误Abort Trap 6
。我不知道为什么会这样。我将感谢任何人提供的任何帮助。提前致谢。
编辑以下是我认为主要问题来自......的功能
void route(char *origin, char *destination, char *airline[])
{
char str[10000];
while (fgets(str, sizeof(str), fp) != NULL)
strcat(str[0], str[1]); // Combining the first element (10) with second element (A)
}
请注意,这段代码仍然不完整,但到目前为止,我还是因为我被困住了。
编辑 10A不是航空公司编号的可能选择。它确实有三个元素,所有航空公司的选择只有两个元素,例如3A。
编辑我添加了使用fgets
函数的行:while (fgets(str, sizeof(str), fp) != NULL)
答案 0 :(得分:0)
继续发表评论(因为看起来你需要帮助才能让灯泡眨眼),让我们来看看你在做什么,而不是做,让你整理出来。首先让我们看一下你的宣言:
void route(char *origin, char *destination, char *airline[]);
void
对于函数类型来说是一个可怕的选择,你需要某种方法来衡量函数的成功/失败(例如在你的情况下找到/未找到)。为type
选择route
,这样您就可以返回值,以在需要时指示成功/失败。 void
有它的位置,例如就像在一个简单的函数中,只需打印输出,你可以在之前验证函数参数将它们传递给函数。否则,使用一种类型,您可以在其中检查返回值以确定函数是成功还是失败。这里有一个简单的int
类型,在失败时返回0
,1
(或任何非零数字,甚至是负数)表示成功。
接下来,char *airline[]
是一个指向char 类型的指针数组。这不是你想要传递像3A
这样的字符串的字符串,它是一个类型为char 的数组(在传递时将转换为指向char * 的指针作为函数参数)或sting文字,它只是指向char 的指针。所以你实际上想要char *airline
。
接下来,除非您将fp
声明为全局文件流指针(糟糕的主意),否则您需要将FILE *fp
作为参数传递给route
。将这些信息放在一起,您对可用route
的声明可以是:
int route (char *origin, char *dest, char *airline, FILE *fp);
根据您在问题中描述的内容,您需要使用fgets
,但目前尚不清楚您实际可用于解析airline
,origin
和{{1}的内容} destination
由str
填充。因此,让我们假设您没有其他功能可以用来分隔字符串,并且让我们使用始终可用的两种基本方法(数组索引和指针算术)从fgets
解析airline
,origin
和destination
。
这是从str
开始并走一个指针(或使用数组索引)来检查每个字符的值并根据需要分配字符(解析单词)的基本方法,直到你有您需要的所有数据,或者到达str
的末尾(您必须防止这两种情况)。
在处理字符串时,由你来记录你的位置,并在合理的程度上预测接下来会发生什么,这样你就可以测试每个角色(对于你是什么)需要,以及字符串的结尾),将它保存在需要保存的地方,或继续将其保存在其他地方。执行此操作时,您需要跟踪已保存到每个位置的字符数(例如,分隔字符数组,如str
,arln
和org
以进行比较您正在寻找的dst
,airline
和origin
,以确保您不会在任何数组的末尾写入,或者分配内存块,记住保存{{1在每个数组的末尾或分配的内存块中保存destination
( nul-byte 或 nul-terminating character )以使每个< em>有效字符串。 (了解+1 char
nul-byte的字符值只有'\0'
,因此您可以使用'\0'
或简单0
来终止字符串)
让我只提供一个注释示例,逐步帮助您理解逻辑(和思想水平),而不是逐步解释可用'\0'
函数的每一行。并且理解在C中做任何事情所需要的,你可以完全控制你如何使用内存,并且你有责任确保你正确使用它 - 以强大的力量来承担很大的责任)。通过以下工作,如果您需要任何特定部分的帮助,请告诉我。
我故意在示例中同时使用数组索引和指针算法,但对于此类型的正常实现,我更喜欢指针算法,原因在于评论。以下所有方法都可以通过多种不同方式完成,例如使用0
来简化读取和解析,或者使用route
或fscanf
来解析填充strtok
按sscanf
。这些函数只是通过将指针(或一对指针)向下移动来帮助您完成手动执行的操作。
我已经验证了str
中传递给fgets
的参数作为示例,但您通常希望在调用此函数之前在调用函数(此处为route
)中执行此操作route
。有了这个,这里有一个可用的main
的例子,它将逐步输入包含格式为:
route
(route
必须出现在每个标识符的末尾,因为它当前已编码,但空格的数量并不重要。airline, origin, destination /* e.g. '3A, KOCH, KEGE' */
也可以正常工作。你有完全控制这一点,只需更改每个角色的测试,您就可以完全消除commas
要求,只需找' 3A, KOCH, KEGE'
来构成每个单词 - 这一切都取决于你。)
','
将读取数据文件中的每一行,0-9, a-z, A-Z
将各个标识符解析为route
,fgets
和arln
,以便与{{1}进行比较}},org
和dst
传递给airline
,如果找到匹配则返回origin
,或者如果找不到匹配则返回destination
。 route
的示例:
1
注意: 0
基本上会做同样的事情三次。从每个标识符的开头开始,将每个字符读入正确的数组,直到找到route
(或* nul-byte), nul-terminate 您的新数组,然后移动到int route (char *origin, char *dest, char *airline, FILE *fp)
{
/* validate parameters - you can do this before calling route */
if (!origin || !*origin) {
fprintf (stderr, "error: origin 'NULL' or empty.\n");
return 0;
}
if (!dest || !*dest) {
fprintf (stderr, "error: dest 'NULL' or empty.\n");
return 0;
}
if (!airline || !*airline) {
fprintf (stderr, "error: airline 'NULL' or empty.\n");
return 0;
}
if (!fp) {
fprintf (stderr, "error: fp not open for reading.\n");
return 0;
}
char str[LINE] = "";
while (fgets (str, LINE, fp)) /* for each line in the input file */
{
char org[PARTS] = "", dst[PARTS] = "", arln[PARTS] = "",
*o = org, *d = dst, *a = arln, *s = str;
size_t n;
/* check for trailing '\n' included by 'fgets' indicating
* complete line read into str, then remove '\n' by overwriting
* with nul-terminating character.
*/
n = strlen (str);
if (str[n - 1] == '\n')
str[--n] = 0;
/* read airline flight from str into arln, will skip leading
* whitespace copying all other chars up to first ',' or '\0'.
* (you can also use strtok to 'tokenize' the line)
*/
/* you can either use array indexing */
for (n = 0; n < PARTS - 1 && s[n] && s[n] != ','; n++) {
if (s[n] == ' ') continue; /* skip space */
a[n] = s[n];
}
a[n] = 0; /* nul-terminate arln (already done, but...) */
s += n; /* indexing wont advance 's', advance to char after 'arln'
* (to the ',') to start looking for beginning of 'org'.
*/
/* or use pointer arithmetic (cleaner as 's' is advanced)
*
* for (n = 0; n < PARTS - 1 && *s && *s != ','; n++, a++, s++) {
* if (*s != ' ') continue;
* *a = *s;
* }
* *a = 0;
*/
/* add checks to validate 'arln' length here if desired, and the same
* following filling 'org' and 'dst' if desired
*/
/* compare arln to airline */
if (strcmp (arln, airline) != 0)
continue; /* doesn't match, get next line */
/* find start of origin (org) in str (using pointer arithmetic)
* skipping forward until you find next '0-9', 'a-z' or 'A-Z'
* (you can use while (*s && isalnum (*s)) from ctype.h instead)
*/
while ( *s && ( (*s < '0' || '9' < *s) &&
(*s < 'a' || 'z' < *s) &&
(*s < 'A' || 'Z' < *s)))
s++;
if (!*s) { /* validate you are not at end of str */
fprintf (stderr, "error: no valid chars follow airline in str.\n");
return 0;
}
/* fill org ICAO from str */
for (n = 0; n < PARTS - 1 && *s && *s != ','; n++, o++, s++)
*o = *s;
*o = 0;
/* compare org to origin */
if (strcmp (org, origin) != 0)
continue; /* doesn't match, get next line */
/* find start of destination (dst) in str (using pointer arithmetic)
* skipping forward until you find next '0-9', 'a-z' or 'A-Z'
* (you can use while (*s && isalnum (*s)) from ctype.h instead)
*/
while ( *s && ( (*s < '0' || '9' < *s) &&
(*s < 'a' || 'z' < *s) &&
(*s < 'A' || 'Z' < *s)))
s++;
if (!*s) { /* validate you are not at end of str */
fprintf (stderr, "error: no valid chars follow origin in str.\n");
return 0;
}
/* fill dst ICAO from str */
for (n = 0; n < PARTS - 1 && *s && *s != ','; n++, d++, s++)
*d = *s;
*d = 0;
/* compare dst to destination */
if (strcmp (dst, dest) == 0)
goto found; /* match for airline, origin, destination found */
}
return 0; /* return 0 - indicating no route found */
found:
return 1; /* return 0 - indicating route found */
}
中的下一个字符,跳过所有内容,直到找到route
(开始下一个标识符),然后重复。
使用它的一个简短例子是:
','
示例输入文件
str
示例使用/输出
0-9, a-z, A-Z
通过这个例子,请确保你理解这一切,如果你没有(在你做出合理的搜索以回答基本语法,等等问题后,请告诉我)