[英]can someone explain this code how to split the string without using strtok?
void filename()
{
char c[50];
FILE *fp;
char d;
int i;
int s[5];
printf("Enter the file name: ");
scanf("%s", c);
fp = fopen(c, "r");
count = 0;
fscanf(fp, "%d$", &id[count]);
while(!feof(fp))
{
fscanf(fp, "%[^$]s)", names[count]);
for(i = 0; i < 5; i++)
{
fscanf(fp, "%c", &d);
fscanf(fp, "%d", &s[i]);
}
grades[count] = ((double)s[0] * 0.15 + (double)s[1] * 0.15 + (double)s[2] * 0.25 + (double)s[3] * 0.1 + (double)s[4] * 0.35);
count++;
fscanf(fp, "%d$", &id[count]);
}
fclose(fp);
}
請向我解釋如何在不使用strtok
的情況下拆分字符串,例如fscanf(fp, "%[^$]s)", names[count]);
我怎樣才能做到這一點?
你的代碼有很多問題。 您錯誤地使用feof
。 您必須始終將寬度修飾符添加到讀取字符串的轉換說明符。 您必須檢查 scanf 返回的值以確保它成功匹配輸入。 我已嘗試對您用來演示預期輸入形式的格式字符串進行最小的更改。 也許讀取未使用的字符 'd' 是嘗試匹配$
,但這不是在您的代碼中強加的(我已在輸入中插入d
以供fscanf(fp, "%c", &d)
讀取) . 由於您沒有提供預期輸入的樣本,我做了一些假設。 如果下面顯示的輸入與您的預期輸入不匹配,您應該修改格式字符串。 我猜你不打算匹配文字s)
,但你當前的代碼需要在輸入中。 而不是更冗長且可能措辭不佳的解釋嘗試:
$ gcc a.c
$ cat input
1$Alice $s)d 10d 5d 10d 15d 7
2$Bob $s)d 11d 6d 11d 16d 8
2$Chuck $s)d 12d 7d 12d 17d 9
$ echo input | ./a.out
Enter the file name: grade for Alice is 8.700000
grade for Bob is 9.700000
grade for Chuck is 10.700000
$ cat a.c
#include <stdio.h>
#include <stdlib.h>
int count;
int id[64];
char names[64][256];
double grades[64];
/* "filename" is a terrible name for a function that reads and parses data */
void
filename(const char *prompt)
{
char path[50];
FILE *fp;
char d;
int i;
double weight[] = { 0.15, 0.15, 0.25, 0.1, 0.35 };
printf("%s: ", prompt);
scanf("%49s", path); /* Always use a width modifier with %s!! */
if( (fp = fopen(path, "r")) == NULL ){
perror(path);
exit(EXIT_FAILURE);
}
count = 0;
while(
count < 64
&& 1 == fscanf(fp, "%d$", id + count)
&& 1 == fscanf(fp, "%255[^$]$s)", names[count])
){
grades[count] = 0;
for(i = 0; i < 5; i++) {
int s;
if( 0
|| 1 != fscanf(fp, "%c", &d)
|| 1 != fscanf(fp, "%d", &s)
){
fprintf(stderr, "Unexpected input\n");
goto end;
}
grades[count] += (double)s * weight[i];
}
printf("grade for %s is %f\n", names[count], grades[count]);
count += 1;
}
end:
fclose(fp);
}
int
main(void)
{
filename("Enter the file name");
return 0;
}
我猜你的意圖是做更多類似的事情:
$ cat input2
1$Alice$ 10 $ 5 $ 10 $ 15 $ 7
2$Bob$ 11 $ 6 $ 11 $ 16 $ 8
3$Chuck$ 12 $ 7 $ 12 $ 17 $ 9
可以解析為:
#include <stdio.h>
#include <stdlib.h>
int count;
int id[64];
char names[64][256];
double grades[64];
void
parse_file(FILE *fp)
{
double weight[] = { 0.15, 0.15, 0.25, 0.1, 0.35 };
count = 0;
while(
count < 64
&& 1 == fscanf(fp, "%d", id + count)
&& 1 == fscanf(fp, "$ %255[^$]", names[count])
){
grades[count] = 0;
for( int i = 0; i < 5; i += 1 ){
int s;
if( 1 != fscanf(fp, " $%d", &s) ){
fprintf(stderr, "Unexpected input\n");
exit(EXIT_FAILURE);
}
grades[count] += (double)s * weight[i];
}
printf("grade for %s is %f\n", names[count], grades[count]);
count += 1;
}
}
int
main(int argc, char **argv)
{
const char *path = argc > 1 ? argv[1] : NULL;
FILE *fp = path ? fopen(path, "r") : stdin;
if( fp == NULL ){
perror(path);
exit(EXIT_FAILURE);
}
parse_file(fp);
fclose(fp);
return EXIT_SUCCESS;
}
請注意,這是功能性的,但肯定不應該被認為是健壯的。 (例如,如果最后一行有額外的 $,程序只會中止而沒有錯誤消息。)完全不清楚你想要什么行為,所以我不打算修改它,而只是說明一下scanf
絕對是錯誤的工具。 它只是一個只能用於教育目的的玩具。 可悲的是,它永遠不應該用於教育目的,而實際上只是一個用來迷惑新手的玩具。 請閱讀http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.