这是我的C编程课,我的老师正在使用scanf,我们不能使用其他任何东西。我正在传递这个文本文件:https://gist.github.com/cjoshmartin/29bd3365a925ee295da21ae2e917c7e1 我正在使用推荐行传递文件与此推荐: program1< lab4text.txt
here is what I am trying to get for output:
| SSN | Average | 263? |
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
1 | xxxx | xx.xxx% | Y |
2 | xxxx | xx.xxx% | N |
3 | xxxx | xx.xxx% | Y |
4 | xxxx | xx.xxx% | Y |
here is what is what I currently am getting:
| SSN | Average | 263 |
-------------------------
1 | 2381 | 67.454 % | Y |
2 | 0 | -167.040 % | 2 |
3 | 0 | 3762321554297869312.000 % | 6 |
4 | 1234 | 81.318 % | Y |
我认为scanf正在从文本文件的错误部分读取,但我不知道如何修复它。
这是我目前的代码:
#include <stdio.h>
void main(void){
//FILE *file;
int i = 0;
int SSN[4] = { 0 }, j;
char isin263[4];
float quizavg[4];
float labavg[4];
float exam1[4];
float exam2[4];
float finalexam[4];
scanf("%*[^\n]\n");
scanf("%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s");
scanf("%*[^\n]\n");
for (i = 0;i < 4;i++)
{
scanf("%*s %*s %*s");
scanf("%*d-%*d-%d", &SSN[i]);
scanf(" %*9s%*c%*c%*c%*c %c %f %f %f %f %f\n", &isin263[i], &quizavg[i], &labavg[i], &exam1[i], &exam2[i], &finalexam[i]);
}
printf("|%5s | %5s | %4d |\n","SSN","Average", 263);
printf("-------------------------\n");
for (j = 0;j < 4;j++)
{
//fixed this line
printf(" %i | %4d | %5.3f %% | %5c |\n",j+1,SSN[j], (quizavg[j]*0.07)+(labavg[j]*0.24)+((exam1[j]+exam2[j])*0.185)+(finalexam[j]*0.32), isin263[j]);
}
}
任何帮助将不胜感激!
答案 0 :(得分:2)
如果您打算尝试使用fscanf
读取不同的数据,那么格式字符串将是您成功(或失败)的关键。如果您需要收集的每一行都具有相同的格式,那么您可以尝试使用fscanf
读取数据(同时通过使用fgets
将读取与解析和解析相关联来获得灵活性和sscanf
)。但是,只要您有办法保留所需的行,并跳过那些不需要的行,那么fscanf
可用作工具。
在这种情况下,您的示例数据LYF_HKN在他的答案中做得很好,因为会计所需的每一行中的所有信息。我只想添加一个小变体并使用类似的东西:
char *fmt = " %*[^\"]\"%[^,], %[^\"]\" %s %s %[YN] %lf %lf %lf %lf %lf";
其余的只是循环输入文件中的行并索引添加到结构中的学生。您需要捕获return
的{{1}}并将其与fscanf
所需的匹配计数进行比较,以验证您的每个值是否已收到输入。您还需要跳过标题行和任何其他不包含学生数据的行。只要10
没有遇到fscanf
在流上设置错误条件,您就可以通过阅读来完成此操作。然后,您只需针对预期的EOF
检查匹配计数(return
),以表明它是否是有效的学生数据行。
将它们放在一起,您可以执行以下操作:
10
使用#include <stdio.h>
/* constants for use in your code */
enum { YN = 2, DOB = 11, SS = 12, NM = 32 };
typedef struct {
char last[NM], first[NM], ss[SS], dob[DOB], yn[YN];
double qavg, lavg, ex1, ex2, fex;
} stnt;
int main (int argc, char **argv) {
stnt s[8] = {{ .first = "" }};
int cnv = 0, n = 0;
char *fmt = " %*[^\"]\"%[^,], %[^\"]\" %s %s %[YN] %lf %lf %lf %lf %lf";
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;
}
/* read each line, if the match-count is 10 increment index */
while ((cnv=fscanf (fp, fmt, s[n].last, s[n].first, s[n].ss, s[n].dob, s[n].yn,
&s[n].qavg, &s[n].lavg, &s[n].ex1, &s[n].ex2, &s[n].fex)) != EOF)
if (cnv == 10) n++;
if (fp != stdin) fclose (fp); /* close file if not stdin */
for (int i = 0; i < n; i++) /* output the student information */
printf ("\n student : %s %s\n ss number : %s\n D.O.B. : %s\n"
" yes/no : %s\n quiz avg : %.2lf\n lab avg : %.2lf\n"
" exam 1 : %.2lf\n exam 2 : %.2lf\n final : %.2lf\n",
s[i].first, s[i].last, s[i].ss, s[i].dob, s[i].yn, s[i].qavg,
s[i].lavg, s[i].ex1, s[i].ex2, s[i].fex);
return 0;
}
和fgets
鉴于有关sscanf
和fgets
的使用的讨论和评论,除了{{1}之外,值得使用我更喜欢的方法的简短示例例子。代码大致相同,只是添加了一个缓冲区sscanf
来保存用户输入行,并根据fscanf
的返回值控制循环。除此之外,用buf
替换fgets
只不过是用缓冲区代替fscanf
调用中的文件流。 sscanf
和sscanf
都会返回匹配计数,它是根据中提供的转化说明符发生的成功转化次数格式字符串。
fscanf
示例使用/输出
使用您的数据(使用其中任何一种),您最终会得到类似于以下内容的输出:
sscanf
答案 1 :(得分:1)
也许this是您正在寻找的。 p>
scala> import ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator
import ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator
scala> val xgb = new XGBoostEstimator("features", "label", Map.empty,10, 2)
This is null
xgb: ml.dmlc.xgboost4j.scala.spark.XGBoostEstimator = XGBoostEstimator_6cd31d495c8f
scala> xgb.uid
res1: String = XGBoostEstimator_6cd31d495c8f