如何将文件中的特定字符串保存到C中的变量

如何将文件中的特定字符串保存到C中的变量,c,file,c-strings,C,File,C Strings,例如,如果我有一个包含以下内容的文件: STUDENTS: Three NAME 1: Andy NAME 2: Becky NAME 3: Chris TYPE: Undergrads 我想把学生的名字提取到一个数组中 我曾尝试使用fscanf实现此功能,例如,此功能有效,我可以将“三”保存到student struct: fscanf(fptr,“学生:%s\n”,student.count) 因此,我尝试了一些变体(count是文件中的行数),但names数组仍然为空: int *num

例如,如果我有一个包含以下内容的文件:

STUDENTS: Three
NAME 1: Andy
NAME 2: Becky
NAME 3: Chris
TYPE: Undergrads
我想把学生的名字提取到一个数组中

我曾尝试使用fscanf实现此功能,例如,此功能有效,我可以将“三”保存到student struct:

fscanf(fptr,“学生:%s\n”,student.count)

因此,我尝试了一些变体(count是文件中的行数),但names数组仍然为空:

int *num = NULL;
*num = 1;
int j;
for (j=0; j<count; j++) {
   if (j != 0 && j != count-1) {
       fscanf(fptr, "NAME %d: %s\n", num, student.names[j]);
       *num+=1;
   }
}

scanf
函数系列不适合扫描具有可变格式的行。在这种情况下,一种合理的方法是首先将输入行作为标记和字符串值扫描,并用冒号分隔

char tag[MAX_TAG_SIZE], value[MAX_VALUE_SIZE];
if (fscanf(f, "%[^:]: %s ", tag, value) != 2) error("bad line format");
此格式字符串将除
以外的任何字符序列输入到
标记中。然后它跳过一个后跟空格的
。然后它将一个非空白字放入
值中
,然后跳过空白(包括换行符)。最后一位获取准备好扫描下一个标记的输入,这一点很重要。新的C程序员在使用scanf时犯的最大错误是忘记正确处理输入流中的空白

现在,您可以检查标记以了解下一步要做什么:

if (strcmp("STUDENTS", tag) == 0) {
   ... Handle students value
} else if(strcmp("TYPE", tag) == 0) {
   ... Handle type value
} else if (strncmp("NAME", tag, 4) == 0) {
    if (sscanf(tag + 4, "%d", &name_number) != 1) error("bad name number");
    ... Handle name_number and value
} else error("unexpected tag");

scanf
函数系列不适合扫描具有可变格式的行。在这种情况下,一种合理的方法是首先将输入行作为标记和字符串值扫描,并用冒号分隔

char tag[MAX_TAG_SIZE], value[MAX_VALUE_SIZE];
if (fscanf(f, "%[^:]: %s ", tag, value) != 2) error("bad line format");
此格式字符串将除
以外的任何字符序列输入到
标记中。然后它跳过一个后跟空格的
。然后它将一个非空白字放入
值中
,然后跳过空白(包括换行符)。最后一位获取准备好扫描下一个标记的输入,这一点很重要。新的C程序员在使用scanf时犯的最大错误是忘记正确处理输入流中的空白

现在,您可以检查标记以了解下一步要做什么:

if (strcmp("STUDENTS", tag) == 0) {
   ... Handle students value
} else if(strcmp("TYPE", tag) == 0) {
   ... Handle type value
} else if (strncmp("NAME", tag, 4) == 0) {
    if (sscanf(tag + 4, "%d", &name_number) != 1) error("bad name number");
    ... Handle name_number and value
} else error("unexpected tag");

请使用调试器遍历此代码。否则,您将永远无法学习如何编写代码。让我们看看你所有的声明。此外,您应该在没有文件的情况下测试代码,在变量中硬编码一些测试数据并使用这些数据进行测试。请包括
student
的声明。另外,为什么要将
num
指针指向int而不仅仅是int?因此,如果我删除该文件,那么我将完全改变我试图完成的文件中的字符串操作情况。我可以通过硬编码轻松填充数组。我将添加Student结构,尽管我也不确定为什么这对于这个特定的问题是必要的(尽管我可能错了)。我将num指针指向int的原因是fscanf似乎不接受int。因此,
num
理想情况下应该是int,然后您应该将
&num
传递给
fscanf
。student的声明很重要,这样我们就可以看到您的代码是否可以将名称输入其中(尽管名称/名称输入错误,但它不会工作)。请使用调试器处理此代码。否则,您将永远无法学习如何编写代码。让我们看看你所有的声明。此外,您应该在没有文件的情况下测试代码,在变量中硬编码一些测试数据并使用这些数据进行测试。请包括
student
的声明。另外,为什么要将
num
指针指向int而不仅仅是int?因此,如果我删除该文件,那么我将完全改变我试图完成的文件中的字符串操作情况。我可以通过硬编码轻松填充数组。我将添加Student结构,尽管我也不确定为什么这对于这个特定的问题是必要的(尽管我可能错了)。我将num指针指向int的原因是fscanf似乎不接受int。因此,
num
理想情况下应该是int,然后您应该将
&num
传递给
fscanf
。学生的声明很重要,这样我们就可以看到你的代码是否可以将名字输入其中(尽管名字/名字输入错误,它也不会起作用)。