[英]Reading in text file in C
我有一個文本文件,如下所示:
sf5 sd6 sh7
或sh7 sd6 sf5
(兩個或其他任意可能的27種組合的任何順序)。
我正在嘗試從中提取值5,6, and 7
但是,我想以任何可能的順序執行此操作,因此sf(somenumber)可以位於這3個位置中的任何一個以及其他兩個位置中。 因此,我試圖將strstr
用作宏之一。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct test
{
char * values;
}test;
int main(int argc, char * argv[])
{
test t;
FILE * file;
char str[100];
int a,b,c;
if(argc > 1)
{
file = fopen(argv[1],"r");
if(file == NULL)
{
exit(1);
}
}
else
{
exit(1);
}
while(fgets(str,100,file) != NULL)
{
t.values = strtok(str," \n");
if(t.values == NULL)
exit(1);
if(strstr(t.values,"sf"))
{
a = atol(t.values+2); // the number two positions after the letter
}
if(strstr(t.values,"sd"))
{
b = atol(t.values+2); // the number two positions after the letter
}
if(strstr(t.values,"sh"))
{
c = atol(t.values+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
}
}
但是,輸出僅對第一個值“ sf5”正確,就好像沒有對后兩個值進行解析一樣。 另外,如果我將“ sf5”移到末尾,則它的值將設置為零,這再次沒有意義。
基本上,只有第一個if
語句才能成功運行。 任何幫助將非常感激!
strstr函數提供搜索到的字符串的位置;如果找不到,則為NULL。 您必須在atol函數中使用此結果才能獲取關聯的值。
在下面的代碼中,我使用變量token
存儲strstr的結果:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, char * argv[])
{
FILE * file;
char str[100];
int a,b,c;
if(argc > 1)
{
file = fopen(argv[1],"r");
if(file == NULL)
{
exit(1);
}
}
else
{
exit(1);
}
while(fgets(str,100,file) != NULL)
{
char *token;
token = strstr(str,"sf"));
if (token != NULL)
{
a = atol(token+2); // the number two positions after the letter
}
token = strstr(str,"sd"));
if (token != NULL)
{
b = atol(token+2); // the number two positions after the letter
}
token = strstr(str,"sh"));
if (token != NULL)
{
c = atol(token+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
}
fclose(file);
}
在每個if塊之前打印t.values的值可能會有所幫助。 它表明t.values不變。 只有第一個if塊的表達式為true。
如果要使用strtok來執行此操作,則...“隨后對str1使用空指針的調用將導致恢復先前保存的位置並從該點開始搜索...”
因此,也許插入strtok(NULL,“ \\ n”)的調用,如下所示:
t.values = strtok(str," \n");
if(strstr(t.values,"sf"))
{
a = atol(t.values+2); // the number two positions after the letter
}
t.values = strtok(NULL," \n"); // get pointer to next token
if(strstr(t.values,"sd"))
{
b = atol(t.values+2); // the number two positions after the letter
}
t.values = strtok(NULL," \n"); // get pointer to next token
if(strstr(t.values,"sh"))
{
c = atol(t.values+2); // the number two positions after the letter
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n",a,b,c);
現在的輸出是
Value of a: 5
Value of b: 6
Value of c: 7
您的代碼有兩個問題:
在使用strstr()
您無需使用返回指針,因此,如果遇到字符串但不是在開頭,它將在錯誤的位置查找數字;
您不會在strtok()
上循環以查找后續的子字符串。 當strtok()
將字符串切成段時,使用strstr()
不會超出第一個分隔符;
這是一種基於您原始方法的替代解決方案(但是由於我打字速度很慢,在此期間,已經有兩個其他有價值的解決方案;-))
while (fgets(str, 100, file) != NULL)
{
t.values = strtok(str, " \t\n");
while (t.values) { // loop to analyse each substring
if (p = strstr(t.values, "sf"))
a = atol(p + 2); // the number two positions after the FOUND string
else if (p = strstr(t.values, "sd"))
b = atol(p + 2); // the number two positions after the letter
else if (p = strstr(t.values, "sh"))
c = atol(p + 2); // the number two positions after the letter
t.values = strtok(NULL, " \t\n");
}
printf("Value of a: %d\n Value of b: %d\n Value of c: %d\n", a, b, c);
}
現在,如果您輸入aaasf5,他將為a找到5,而之前則為0。
此代碼(也不包含您的代碼)解決了找不到其中一個值的情況。 因此,您應該將a,b,c初始化為默認值,例如0。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.