我试图从文件中读取符合以下内容的行:
String1 A
String2 B
String3 C
等。
并将它们存储在两个独立的结构数组中; stringName和group。 我发现的所有内容都是用符号或其他类似的代码分隔的字符串,但不是同一个问题
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include <math.h>
#include "string.h"
struct StringStruct {
char Stringname[16];
char group[1];
}String[100];
int MaxNumLines = 100, i;
char str[25];
int main()
{
// open String.dat file as a read from file
FILE *fp1;
errno_t string_file = fopen_s(&fp1, "String.dat", "r");
// if String.dat not found,
if (fp1 == NULL)
{
// print error
printf_s("Error: String.dat not found\n");
exit(0);
}
// if String.dat found
else
{
// print success
printf_s("File String.dat opened successfully\n");
}
// read names and assign groups
while (fscanf_s(fp1, "%s %s", String[i].Stringname, String[i].group) != EOF)
{
// read names one line at a time
for (i = 0; i < MaxNumLines; i++)
{
// read string name
scanf_s(str, "%s %s", String[i].Stringname, String[i].group);
}
}
for (i = 0; i < MaxNumLines; i++)
{
printf_s("%-12s", String[i].Stringname);
printf_s("%s", String[i].group);
}
}
}
现在,在我看来,一切都应该有效,但事实并非如此,而且我也得到了fscanf_s警告:
- 警告C4477:&#39; fscanf_s&#39; :格式字符串&#39;%s&#39;需要类型为&#39; unsigned int&#39;的参数,但是可变参数2的类型为&#39; char *&#39;
- 注意:此参数用作缓冲区大小
- 警告C4473:&#39; fscanf_s&#39; :没有为格式字符串
传递足够的参数- 注意:占位符及其参数需要4个可变参数,但提供了2个
- 注意:格式字符串&#39;%s&#39;
需要缺少可变参数3- 注意:此参数由转换说明符
使用
但是我已经查看了fscanf_s函数,所有内容似乎都符合它的使用说明。
我不是最熟练的C,但到目前为止我一直在学习它,而且我一直试图找到解决这些问题的方法。几天,但在那个时候没有取得任何进展。
答案 0 :(得分:0)
使用scanf_s
系列函数时,格式说明符%s
,%c
和%[
期望两个参数,而不是一个。第一个是指向应该存储数据的缓冲区的指针,第二个是该缓冲区的大小。
对于您的代码,它看起来像这样:
fscanf_s(fp1, "%s %s", String[i].Stringname, 16, String[i].group, 1)
请注意,常规scanf
系列函数只接受这些格式的一个参数(指向缓冲区的指针)。
可以找到有关这些功能的更多信息here。
答案 1 :(得分:0)
#include "stdio.h"
#include "stdlib.h"
#include <math.h>
#include "string.h"
struct Stringstruct
{
char Stringname[16];
char *group;
};
int MAX_LINE = 100;// max count of chars in one line
int main()
{
// open String.dat file as a read from file
FILE *fp1;
errno_t string_file = fopen_s(&fp1, "String.dat", "r");
char *sep = " \n";//split the string line into tokens.
char *token = NULL;
char *next_token = NULL;
char buf[100];//100 is the max chars number of one line
if (fp1 == NULL) {
// print error
printf_s("Error: String.dat not found\n");
exit(0);
}
else
{
// print success
printf_s("File String.dat opened successfully\n");
}
//get the line count of the file, allocate memory to the array dynamically
int linecount = 0;
while (fgets(buf, MAX_LINE, fp1) != NULL)
{
linecount++;
}
struct Stringstruct *myarray = malloc(sizeof(struct Stringstruct)* linecount);
//back to the start of the file and process the strings line by line
rewind(fp1);
int i = -1;
while (fgets(buf, sizeof(buf), fp1))//read the file line by line
{
i++;
token = strtok_s(buf, sep, &next_token);
int temp = strlen(token);
strcpy_s(myarray[i].Stringname, strlen(token)+1, token);
//since there's newline chars at the end of the string line, like '\n' or '\r\n'
//normally it will loop for two times,
//add the exception processing in this block
while (token != NULL)
{
// Get next token:
if (token != NULL)
{
//printf(" %s\n", token);
token = strtok_s(NULL, sep, &next_token);
int temp = strlen(token);
myarray[i].group = malloc(sizeof(char));
strcpy_s(myarray[i].group, strlen(token) + 1, token);
break;
}
}
//if the index exceed, stop the loop
if (i >= linecount) {
printf_s("Error: array mystring over flow\n");
break;
}
}
fclose(fp1);//close the file
for (i = 0; i < linecount; i++)
{
printf_s("%-12s", myarray[i].Stringname);
printf_s("%s\n", myarray[i].group);
myarray[i].group = NULL;
}
free(myarray);
myarray = NULL;
system("PAUSE");
return 0;
}
答案 2 :(得分:0)
奥卡姆剃刀。我不确定我的问题是否明确,但我发现了一个非常简单的解决方案:
for(i=0;i<num_strings;i++)
{
fscanf_s(fp, "%16s", String[i].name, 16);
fscanf_s(fp, "%2s", String[i].group, 2);
}
16是最大名称长度+ ~2,2是组字符串的舒适大小。
将这些打印在另一个for循环中确认它们起作用,至少对我来说。 对不起,如果这对退伍军人来说是一种显而易见的方法,但是作为我的新手,我不知道该问什么。
感谢那些帮助过的人!