接下來,除非你聲明fp
爲全局文件流指針(壞主意),你需要通過FILE *fp
作爲參數傳遞給route
。一起把這個信息,你的聲明可用route
可以是這樣的:
int route (char *origin, char *dest, char *airline, FILE *fp);
從你在你的問題描述你需要使用fgets
什麼,但它是在什麼實際可用解析不清楚airline
,origin
和destination
來自str
由fgets
填充。因此,讓我們只是假設你有你可以用它來分隔字符串,我們使用的是始終可用的兩種基本方法(數組索引和指針運算)來解析airline
,從str
origin
和destination
沒有其他功能。
這是從str
開始處開始並漫遊指針(或使用數組索引)檢查每個字符的值並根據需要分配字符(解析字)直到獲得所有數據的基本方法您需要或到達str
的末尾(您必須針對這兩種情況進行保護)。
當工作下來一個字符串,它是由你來跟蹤你在哪裏,並預測到合理程度的下一步怎麼走,所以你可以測試每個字符(你需要什麼,以及至於字符串的結尾),將其保存在需要保存的位置,或者繼續保存到其他位置。當你這樣做時,你需要跟蹤你保存到每個單獨位置的字符數(例如分隔字符數組,如arln
,org
和dst
,以便與要查找的airline
,origin
和destination
進行比較)確保你不寫超出了任何陣列,或分配的內存塊的結尾,記住保存+1 char
在每個陣列的端部以保持'\0'
(NUL字節或NUL-終止字符)或分配內存塊使每個有效字符串。(明白'\0'
的NUL字節具有的簡單0
一個字符值,所以你可以使用'\0'
或者乾脆0
終止字符串)
而不是通過解釋什麼可用route
功能可能看起來像每行一步,讓我只是提供一個評論性的例子,它逐步地幫助你理解邏輯(以及C語言中幾乎任何事物所需要的思考和理解水平,你完全控制你如何使用內存,並且你有確保您正確使用它的全部責任 - 以巨大的權力來承擔重大責任)。儘管如此,請讓我知道你是否需要任何特定部分的幫助。
我故意使用兩種陣列中的示例索引和指針運算,但對於一個正常執行這種類型的,我寧願指針運算在評論中所指出的原因。下面的一切可以做一些採用例如fscanf
簡化讀取和一次或使用strtok
或sscanf
解析str
由fgets
充滿解析不同的方式。這些函數只是幫助你做任何你可以隨時通過沿着任何字符串走一個指針(或一對指針)手動執行的操作。
我已經驗證傳遞給route
在route
作爲例子的參數,但通常你會想要讓您的呼叫route
之前做的是,在調用函數(main
這裏)。用,這裏是一個可用route
一個例子,將步驟雖然含有線的輸入文件格式爲:
airline, origin, destination /* e.g. '3A, KOCH, KEGE' */
(所述commas
必須存在於每個標識符的端部,因爲它是當前編碼的,但空格數量並不重要' 3A, KOCH, KEGE'
會正常工作,以及你在這個完全控制,並簡單地通過改變每個字符的測試,你可以完全消除','
要求,只是看0-9, a-z, A-Z
彌補每個單詞。 - - 這一切都取決於你)
route
將與數據文件讀取每一行。 fgets
解析各個標識符爲arln
,org
和dst
來比較airline
,origin
和destination
傳遞給route
,返回1
如果發現匹配,或0
出現錯誤時或沒有找到匹配。對於route
的例子:
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
本質上是做同樣的事情三倍。開始在每個標識符的開始,讀取每個字符到適當的陣列,直到','
(或* NUL字節)被發現,NUL,終止新的數組,然後移動到下一個字符str
,跳過一切,直到找到0-9, a-z, A-Z
(開始下一個標識符),然後重複。
其使用的簡短的例子是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { PARTS = 8, LINE = 128 }; /* constants - adjust as required */
/* specify a meaningful return type to guage success/failure */
int route (char *origin, char *dest, char *airline, FILE *fp);
int main (int argc, char **argv) {
char *ar = "3A", *or = "KOCH", *ds = "KEGE"; /* flight to find */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
if (route (or, ds, ar, fp))
printf ("airline '%s' origin '%s' destination '%s' -- found.\n",
ar, or, ds);
else
printf ("airline '%s' origin '%s' destination '%s' -- not found.\n",
ar, or, ds);
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
int route (char *origin, char *dest, char *airline, FILE *fp)
{
...
}
實施例輸入文件
$ cat dat/route.txt
1D, KEFD, KPRS
3A, KOCH, KEGE
8Z, KDT0, 3T2
實施例使用/輸出雖然示例
$ ./bin/airline <dat/route.txt
airline '3A' origin 'KOCH' destination 'KEGE' -- found.
工作,確保你解開這一切,讓我知道如果你不(在你已經做出合理的搜索回答基本語法等問題你的自我)
是的,你可以使用'strcmp'來比較兩個字符串。如果您需要任何調試幫助,您需要發佈[mcve],因爲我們無法讀懂您的想法,並告訴您爲什麼您的程序錯誤。我會建議編輯你的問題,以減少很多文本;只是簡單描述你的目標,展示問題的最小代碼,說出你期望的輸出,並說出你得到的輸出。 –
'strcat(str [0],str [1]);'肯定是一個問題。 'str *'適用於字符串,但是您提供了單個字符。你的意思是'str [0] = str [1];'而不是?這仍然是錯誤的,因爲'str'是未初始化的。但我認爲你有更多的代碼在初始化它? –
「_10(將存儲在str [0]中)_」 - 不。你不能那樣做。 '10'包含_two_字符'1'和'0',它們需要存儲在不同的變量中。你不能在一個變量中存儲很多值,對吧? Maybd你需要'str [strchr(str,',') - str] ='\ 0';'? –