我想读取文件中的每一行,如下所示:
readEveryLine
{
"Bart [m]" -> "Marge [f]";
"Lisa [f]" -> "Homer [m]";
...
}
我想使用:
- fgets() 逐行读取文件
- strncmp() 将每一行与给定字符串进行比较或查看其格式是否正确
我有什么:
while(fgets(*file_string, MAX_INPUT_STDIN, file) != NULL)
{
changeLastC(*file_string); // function to change \n into \0
if (strncmp(*file_string, "readEveryLine\0", 14) == 0)
{
if (strncmp(*file_string, "{\0", 2) == 0)
{
// check the first -> relation
}
}
else
{
printf("Error Parsing\n");
}
}
所以问题是它只是给了我一个错误解析,我不知道我在这里做错了什么。
非常感谢您对我的帮助!
这里我现在做了一些事情(现在可以解析前两行): 也许有人给了我一个很好的建议,我可以做得更好。 非常感谢。
if ((fp = fopen("df.dot","r")) == NULL)
{
printf("Error: File Open\n");
return 1;
}
int row = 0; // check row 1
while (fgets(buffer, MAX_PARSING, fp))
{
if ((row == 0) && strncmp(buffer, "readEveryLine\n", 14) == 0)
{
printf("%s", buffer);
}
else
{
printf("Parsing Error 1\n");
}
}
int row1 = 1; // check row 2
while (fgets(buffer, MAX_PARSING, fp))
{
if ((row1 == 1) && strncmp(buffer, "{\n", 2) == 0)
{
printf("%s", buffer);
}
else
{
printf("Parsing Error 2\n");
}
}
int row2 = 2; // check other rows (dynamic, could be even more or less)
while (fgets(buffer, MAX_PARSING, fp))
{
if ((row2 == 2) && strncmp(buffer, " ", 2) == 0)
{
const char *p1 = strstr(fp, "\"")+1;
const char *p2 = strstr(p1, " [m]\"");
const char *p3 = strstr(p1, " [f]\"");
// extract male persons
if (p1 && p2)
{
size_t len1 = p2 - p1;
char* res1 = (char*)malloc(sizeof(char)*(len1 + 1));
strncpy(res1, p1, len1);
res1[len1] = '\0';
// give res1 for functionMale() to work on that string
}
// extract female persons
else if (p1 && p3)
{
size_t len2 = p3 - p1;
char* res2 = (char*)malloc(sizeof(char)*(len2 + 1));
strncpy(res2, p1, len2);
res2[len2] = '\0';
// give res2 for functionFemale() to work on that string
}
else if (strcmp(buffer, " -> ") == 0)
{
// work in progress (quite complicated to do this i think)
// it has to be a realtion between two people
}
else if (strcmp(buffer, ";") == 0)
{
// work in progress
// this sign can either exist like this:
// "Bart [m]" -> "Marge [f]";
// or like this:
// "Marge [f]";
}
break;
}
else
{
printf("Parsing Error 3\n");
}
row2++;
}
//最后一个符号必须是 }\n
最佳答案
你的算法已经被破坏了。
您使用 *file_string
的完全相同的内容将其与两个不同的字符串进行比较。
如果您找到 "readEveryLine"
的匹配项,则需要先从文件中读取下一行,然后才能获取 strncmp()
的下一个匹配项。
否则,文件中的行必须匹配 "readEveryLine"
和 "{"
才能传递第二个 if
条件,这是不可能的。
编辑: 现在,尽管您已经做了一些改进,但我仍然认为它不适用于您的方法。循环在应该退出时不会退出,并且您的 if-else 级联似乎也不是一个好主意。 在你的方法中,你会因为读取太多行而只需要解析 1 行而陷入困境。
也许您应该阅读一些有关状态机的内容。
这是我解决问题的快速方法:
enum { STATE_HEADER1, STATE_HEADER2, STATE_BODY, STATE_END} state;
int done = 0;
state = STATE_HEADER1;
while (fgets(buffer, MAX_PARSING, fp) && !done) {
if (state == STATE_HEADER1) {
if (strcmp(buffer, "readEveryLine\n") == 0) {
printf("%s", buffer);
state = STATE_HEADER2;
}
else {
printf("Parsing Error 1\n");
done = 1;
}
}
else if (state == STATE_HEADER2) {
if (strcmp(buffer, "{\n") == 0) {
printf("%s", buffer);
state = STATE_BODY;
}
else {
printf("Parsing Error 2\n");
done = 1;
}
}
else if (state == STATE_BODY) {
if (strcmp(buffer, " ") == 0) {
const char *p1 = strstr(buffer, "\"");
const char *pm = strstr(p1, " [m]\"");
const char *pf = strstr(p1, " [f]\"");
char *res;
const char *ptemp;
int is_male;
if (p1 && pf) {
p1 ++;
is_male = 0;
size_t len1 = pf - p1;
res = malloc(len1 + 1);
strcpy(res, p1);
ptemp = pf+3; // point after closing \"
// give res for functionFemale() to work on that string
}
else if (p1 && pm) {
p1 ++;
is_male = 1;
size_t len1 = pm - p1;
res = malloc(len1 + 1);
strcpy(res, p1);
ptemp = pm+3; // point after closing \"
// give res for functionMale() to work on that string
}
else {
done = 1;
printf("Parsing Error 2\n");
}
// Now we have res and is_male holding name and gender.
if (!done)
{
if (strncmp(ptemp, " -> ", 4) == 0) {
// Handle this variant:
// this sign can either exist like this:
// "Bart [m]" -> "Marge [f]";
// Do similar stuff as above for first name
// Get second name + gender
// Also check trailing ';' here
}
else if (strcmp(temp, ";\n") == 0) {
// Handle this variant:
// or like this:
// "Marge [f]";
}
} // found " "
else {
if (strcmp(buffer, "}\n") == 0) {
state = STATE_END;
done = 1;
printf("That's it folks...\n");
}
else {
done = 1;
printf("Parsing Error 3\n");
}
}
}
} // STATE_BODY
} // while (fgets)
if (state == STATE_END) }
// Success. :)
} else {
// Something didn't match.
}
// close file, cleanup, etc.
我还没有编译它,但你应该明白了。
关于c - 使用 fgets 从文件中读取行并将每一行与 c 中的 strncmp 进行比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41429332/