循环中的scanf(";%[^\n]]*c";,&x2026;)

循环中的scanf(";%[^\n]]*c";,&x2026;),c,scanf,C,Scanf,我必须编写一个新文件,其中必须在一行中包含多个学生信息(如:学生姓名、学生姓氏、学校科目和学生人数),并且我必须输入新学生,直到输入结束 我必须使用printf和scanf。姓名、姓氏和主题可以是多个单词。当我尝试使用scanf([^\n]*c,Name)时,我只能输入一个学生的信息,循环只会忽略其余学生,而对于其他学生,我可以只键入整数学生编号 我的代码有什么问题 int main() { FILE *outputfile = NULL; struct imenik {

我必须编写一个新文件,其中必须在一行中包含多个学生信息(如:
学生姓名、学生姓氏、学校科目和学生人数),并且我必须输入新学生,直到输入结束

我必须使用printf和scanf。姓名、姓氏和主题可以是多个单词。当我尝试使用
scanf([^\n]*c,Name)
时,我只能输入一个学生的信息,循环只会忽略其余学生,而对于其他学生,我可以只键入整数学生编号

我的代码有什么问题

int main() {
    FILE *outputfile = NULL;

    struct imenik {
        char prezime[17 + 1];
        char ime[13 + 1];
        char predmet[20 + 1];
        int bodovi;
    } ucenik;

    outputfile = fopen("imenik.txt", "w");   

    printf("Ucitaj ime ucenika: ");
    scanf("%[^\n]%*c", ucenik.ime);

    printf("Ucitaj prezime ucenika: ");
    scanf("%[^\n]%*c", ucenik.prezime);

    printf("Ucitaj predmet: ");
    scanf("%[^\n]%*c", ucenik.predmet);

    printf("\nUcitaj broj bodova (0-50): ");
    scanf("%d", &ucenik.bodovi);

    fprintf(outputfile, "%s | %s | %s | %d\n", ucenik.ime, ucenik.prezime, ucenik.predmet, ucenik.bodovi);
    fclose(outputfile);    

}
问题在于:

scanf("%d", &ucenik.bodovi);
它读取数字,但不读取其后的换行符。因此,当循环重复时,它会将该换行作为下一个学生姓名的空行输入读取

您可以将其更改为:

scanf("%d ", &ucenik.bodovi);
printf("Ucitaj ime ucenika: ");
scanf(" %[^\n]", ucenik.ime);

printf("Ucitaj prezime ucenika: ");
scanf(" %[^\n]", ucenik.prezime);

printf("Ucitaj predmet: ");
scanf(" %[^\n]", ucenik.predmet);

printf("\nUcitaj broj bodova (0-50): ");
scanf("%d", &ucenik.bodovi);
空格告诉它跳过数字后面的任何空格

但实际上,最好将空格放在每个
scanf
的开头,而不是忽略末尾的换行符。有关解释,请参阅。因此,将其更改为:

scanf("%d ", &ucenik.bodovi);
printf("Ucitaj ime ucenika: ");
scanf(" %[^\n]", ucenik.ime);

printf("Ucitaj prezime ucenika: ");
scanf(" %[^\n]", ucenik.prezime);

printf("Ucitaj predmet: ");
scanf(" %[^\n]", ucenik.predmet);

printf("\nUcitaj broj bodova (0-50): ");
scanf("%d", &ucenik.bodovi);
问题在于:

scanf("%d", &ucenik.bodovi);
它读取数字,但不读取其后的换行符。因此,当循环重复时,它会将该换行作为下一个学生姓名的空行输入读取

您可以将其更改为:

scanf("%d ", &ucenik.bodovi);
printf("Ucitaj ime ucenika: ");
scanf(" %[^\n]", ucenik.ime);

printf("Ucitaj prezime ucenika: ");
scanf(" %[^\n]", ucenik.prezime);

printf("Ucitaj predmet: ");
scanf(" %[^\n]", ucenik.predmet);

printf("\nUcitaj broj bodova (0-50): ");
scanf("%d", &ucenik.bodovi);
空格告诉它跳过数字后面的任何空格

但实际上,最好将空格放在每个
scanf
的开头,而不是忽略末尾的换行符。有关解释,请参阅。因此,将其更改为:

scanf("%d ", &ucenik.bodovi);
printf("Ucitaj ime ucenika: ");
scanf(" %[^\n]", ucenik.ime);

printf("Ucitaj prezime ucenika: ");
scanf(" %[^\n]", ucenik.prezime);

printf("Ucitaj predmet: ");
scanf(" %[^\n]", ucenik.predmet);

printf("\nUcitaj broj bodova (0-50): ");
scanf("%d", &ucenik.bodovi);

我建议您采用如下实现方式:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define S_SIZE 32
#define T_SIZE 128
int main(void) {
    FILE *outputfile = NULL;

    struct imenik {
        char prezime[S_SIZE];
        char ime[S_SIZE];
        char predmet[S_SIZE];
        int bodovi;
    } ucenik;

    outputfile = fopen("imenik.txt", "a");
    if (outputfile == NULL) {
        perror("Fopen");
        exit(EXIT_FAILURE);
    }
    char tmp[T_SIZE];

    while (1) {
        printf("Enter info separated with spaces: ");
        fgets(tmp, T_SIZE, stdin);
        if (strcmp(tmp, "END\n") == 0) {
            break;
        }
        sscanf(tmp, "%s %s %s %d", ucenik.ime, ucenik.prezime, ucenik.predmet, &ucenik.bodovi);
        fprintf(outputfile, "%s | %s | %s | %d\n", ucenik.ime, ucenik.prezime, ucenik.predmet, ucenik.bodovi);
    }
    fclose(outputfile);

    return 0;
}
#包括
#包括
#包括
#定义S_尺寸32
#定义T_大小128
内部主(空){
FILE*outputfile=NULL;
结构imenik{
char prezime[S_SIZE];
字符输入法[S_大小];
char premet[S_SIZE];
博多维国际酒店;
}乌塞尼克;
outputfile=fopen(“imenik.txt”,“a”);
if(outputfile==NULL){
佩罗尔(“福彭”);
退出(退出失败);
}
字符tmp[T_大小];
而(1){
printf(“输入信息,用空格分隔:”);
fgets(tmp、T_尺寸、标准尺寸);
if(strcmp(tmp,“END\n”)==0){
打破
}
sscanf(tmp,“%s%s%s%d”、ucenik.ime、ucenik.prezime、ucenik.predmet和ucenik.bodovi);
fprintf(输出文件,“%s |%s |%s |%d\n”、ucenik.ime、ucenik.prezime、ucenik.predmet、ucenik.bodovi);
}
fclose(输出文件);
返回0;
}

我建议您采用如下实施方式:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define S_SIZE 32
#define T_SIZE 128
int main(void) {
    FILE *outputfile = NULL;

    struct imenik {
        char prezime[S_SIZE];
        char ime[S_SIZE];
        char predmet[S_SIZE];
        int bodovi;
    } ucenik;

    outputfile = fopen("imenik.txt", "a");
    if (outputfile == NULL) {
        perror("Fopen");
        exit(EXIT_FAILURE);
    }
    char tmp[T_SIZE];

    while (1) {
        printf("Enter info separated with spaces: ");
        fgets(tmp, T_SIZE, stdin);
        if (strcmp(tmp, "END\n") == 0) {
            break;
        }
        sscanf(tmp, "%s %s %s %d", ucenik.ime, ucenik.prezime, ucenik.predmet, &ucenik.bodovi);
        fprintf(outputfile, "%s | %s | %s | %d\n", ucenik.ime, ucenik.prezime, ucenik.predmet, ucenik.bodovi);
    }
    fclose(outputfile);

    return 0;
}
#包括
#包括
#包括
#定义S_尺寸32
#定义T_大小128
内部主(空){
FILE*outputfile=NULL;
结构imenik{
char prezime[S_SIZE];
字符输入法[S_大小];
char premet[S_SIZE];
博多维国际酒店;
}乌塞尼克;
outputfile=fopen(“imenik.txt”,“a”);
if(outputfile==NULL){
佩罗尔(“福彭”);
退出(退出失败);
}
字符tmp[T_大小];
而(1){
printf(“输入信息,用空格分隔:”);
fgets(tmp、T_尺寸、标准尺寸);
if(strcmp(tmp,“END\n”)==0){
打破
}
sscanf(tmp,“%s%s%s%d”、ucenik.ime、ucenik.prezime、ucenik.predmet和ucenik.bodovi);
fprintf(输出文件,“%s |%s |%s |%d\n”、ucenik.ime、ucenik.prezime、ucenik.predmet、ucenik.bodovi);
}
fclose(输出文件);
返回0;
}
您的线路:

scanf("%d", &ucenik.bodovi);
在输入流中保留换行符。下一次调用
scanf()
,它会立即退出,并留下换行符,依此类推。不要尝试向格式字符串中添加尾随空白字符,正如一些人建议的那样:
“%d”
。这将使用输入末尾的换行符,并等待更多输入,直到遇到非空白字符或
EOF

最简单的解决方案是执行您已经在执行的操作以丢弃换行符:

scanf("%d%*c", &ucenik.bodovi);
请注意,使用
scanf()
读取字符串时,应在格式字符串中指定最大宽度,以避免缓冲区溢出:

scanf("%13[^\n]%*c", ucenik.ime);
此外,您应该检查
outputfile
,以确保文件已成功打开

实现循环的一种方法是将第一个对
scanf()
的调用放在循环外部,然后在
while
语句中使用
strcmp()
检查
“END”
。在循环结束时,复制对
scanf()
的第一个调用:

#包括
#包括
#包括
内部主(空){
FILE*inputfile=NULL;
FILE*outputfile=NULL;
结构imenik{
char-prezime[17+1];
字符输入法[13+1];
char-premet[20+1];
博多维国际酒店;
}乌塞尼克;
outputfile=fopen(“imenik.txt”,“w”);
/*文件打开成功了吗*/
if(outputfile==NULL){
perror(“无法打开文件:”);
退出(退出失败);
}
/*在对scanf()的调用中指定最大宽度*/
printf(“Ucitaj-ime-ucenika:”);
scanf(“%13[^\n]%*c”,ucenik.ime);
while(strcmp(ucenik.ime,“END”)!=0){
printf(“Ucitaj prezime ucenika:”);
scanf(“%17[^\n]%*c”,ucenik.prezime);
printf(“Ucitaj predmet:”);
scanf(“%20[^\n]%*c”,ucenik.predmet);
printf(“\nUcitaj broj bodova(0-50):”;
scanf(“%d%*c”&ucenik.bodovi);
fprintf(输出文件,“%s |%s |%s |%d\n”,
ucenik.ime、ucenik.prezime、ucenik.premet、ucenik.bodovi);
printf(“Ucitaj-ime-ucenika:”);
scanf(“%13[^\n]%*c”,ucenik.ime);
}
fclose(输出文件);
返回0;
}
您的线路:

scanf("%d", &ucenik.bodovi);
在输入流中保留换行符。下一次调用
scanf()
,它会立即退出,并留下换行符,依此类推。不要尝试向格式字符串中添加尾随空白字符,正如一些人建议的那样:
“%d”
。这将使用输入末尾的换行符,并等待更多输入,直到出现非空白字符