将 [^\n] 添加到 scanf_s 时,for 循环不起作用
For loop doesn`t work when add [^\n] to a scanf_s
该程序应该要求您将成员(人员)添加到结构并将它们打印到文件中,但在第一个 for 循环之后停止工作并跳过名称部分。我刚刚发现允许您将 space 添加到字符串的东西,尝试过但没有成功......
我试图删除它并且它可以正常工作,所以 [^\n]
出了点问题。
怎么了?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Staff {
char Surname[100];
char Name[100];
int age;
char spec[100];
int id;
} person;
void write();
void leggi();
void trova();
int main() {
write();
}
void write() {
int i = 0;
int n = 1;
int r;
FILE *fp;
fopen_s(&fp, "index.txt", "w+");
if (fp == NULL) {
printf("Failed to open file\n");
exit(1);
}
fprintf(fp, "%d\n", i);
for (i = 0; i < n; i++) {
printf("Surame:\n");
scanf_s("%[^\n]s", person.Surname, 100);
fprintf(fp, "%s\t\t", person.Surname);
//loop just get over the name part
printf("Name:\n"); //after the first loop
scanf_s("%s", person.Name, 100);
fprintf(fp, "%s\t", person.Name);
printf("Age:\n");
scanf_s("%d", &person.age);
fprintf(fp, "%d\t", person.age);
printf("Specialization\n");
scanf_s("%s", person.spec, 100);
fprintf(fp, "%s\n", person.spec);
printf("Want to enter another? 1=yes 0=no...\n");
scanf_s("%d", &r);
if (r == 1)
n = n + 1;
}
rewind(fp);
fprintf(fp, "%d\n", i);
fclose(fp);
}
通过在格式字符串的开头插入 space 来更改下面用于输入字符串的 scanf 调用。例如,而不是这个调用
scanf_s("%[^\n]s", person.Surname, 100);
(其中字母 s
必须从格式字符串中删除)写
scanf_s(" %[^\n]", person.Surname, ( rsize_t )100);
^^^^^^^^
这允许跳过输入缓冲区中前导的白色 space 字符。
注意你正在做的改变条件或for循环
for (i = 0; i < n; i++) {
//...
if (r == 1)
n = n + 1;
}
使代码不清楚。您可以使用 do-while 循环代替 for 循环。
您的代码中存在多个问题:
你使用了所谓的secure函数fopen_s
、scanf_s
等等,但是你没有检查return 值来检测无效输入。您应该改用标准函数,传递适当的参数并检查 return 值。
using scanf_s
实际上是不可移植的:C 标准附件 K 中定义的 scanf_s
函数要求指针后的长度参数具有 size_t
类型,而 Microsoft 库中具有相同名称的函数使用类型 UINT
,它在其 Windows OS 的 64 位版本上具有不同的表示形式。 Embrace, enhance and extinguish 策略的经典案例。在标准 C 中,应该写成:scanf_s("%s", person.Name, (size_t)100)
或更好:
scanf_s("%s", person.Name, sizeof person.Name)
无需使用 "w+"
打开输出文件进行更新,只需使用 "w"
.
您将流指针倒回文件开头并覆盖文件开头的条目数。只要您的条目少于 10 个,此方法就有效,但除此之外,该数字的位数更多,因此文件中的某些字符将被损坏。您可以使用带填充的格式,例如 "%6d\n"
,这样可以无风险地容纳多达 100 万条记录。
"%[^\n]s"
不是正确的 scanf
格式:您应该只写 "%[^\n]"
或更好的 " %99[^\n]"
以跳过初始白色 space 并将输入限制为 99 个字符。
这是修改后的版本:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Staff {
char Surname[100];
char Name[100];
int age;
char spec[100];
int id;
};
void write(void);
void leggi(void);
void trova(void);
int main() {
write();
}
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
void write(void) {
int n = 0;
int r;
FILE *fp = fopen("index.txt", "w");
if (fp == NULL) {
fprintf("Failed to open file index.txt: %s\n",
strerror(errno));
exit(1);
}
fprintf(fp, "%6d\n", n);
for (;;) {
struct Staff person = { 0 };
printf("Surname:\n");
if (scanf(" %99[^\n]", person.Surname) != 1)
break;
flush_input();
fprintf(fp, "%s\t\t", person.Surname);
//loop just get over the name part
printf("Name:\n"); //after the first loop
scanf(" %99[^\n]", person.Name);
flush_input();
fprintf(fp, "%s\t", person.Name);
printf("Age:\n");
scanf("%d", &person.age);
flush_input();
fprintf(fp, "%d\t", person.age);
printf("Specialization\n");
scanf(" %99[^\n]", person.spec, 100);
flush_input();
fprintf(fp, "%s\n", person.spec);
n++;
printf("Want to enter another? 1=yes 0=no...\n");
if (scanf("%d", &r) != 1 || r != 1) {
flush_input();
break;
}
flush_input();
}
rewind(fp);
// update the entry count on 6 characters
fprintf(fp, "%6d\n", n);
fclose(fp);
}
该程序应该要求您将成员(人员)添加到结构并将它们打印到文件中,但在第一个 for 循环之后停止工作并跳过名称部分。我刚刚发现允许您将 space 添加到字符串的东西,尝试过但没有成功......
我试图删除它并且它可以正常工作,所以 [^\n]
出了点问题。
怎么了?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Staff {
char Surname[100];
char Name[100];
int age;
char spec[100];
int id;
} person;
void write();
void leggi();
void trova();
int main() {
write();
}
void write() {
int i = 0;
int n = 1;
int r;
FILE *fp;
fopen_s(&fp, "index.txt", "w+");
if (fp == NULL) {
printf("Failed to open file\n");
exit(1);
}
fprintf(fp, "%d\n", i);
for (i = 0; i < n; i++) {
printf("Surame:\n");
scanf_s("%[^\n]s", person.Surname, 100);
fprintf(fp, "%s\t\t", person.Surname);
//loop just get over the name part
printf("Name:\n"); //after the first loop
scanf_s("%s", person.Name, 100);
fprintf(fp, "%s\t", person.Name);
printf("Age:\n");
scanf_s("%d", &person.age);
fprintf(fp, "%d\t", person.age);
printf("Specialization\n");
scanf_s("%s", person.spec, 100);
fprintf(fp, "%s\n", person.spec);
printf("Want to enter another? 1=yes 0=no...\n");
scanf_s("%d", &r);
if (r == 1)
n = n + 1;
}
rewind(fp);
fprintf(fp, "%d\n", i);
fclose(fp);
}
通过在格式字符串的开头插入 space 来更改下面用于输入字符串的 scanf 调用。例如,而不是这个调用
scanf_s("%[^\n]s", person.Surname, 100);
(其中字母 s
必须从格式字符串中删除)写
scanf_s(" %[^\n]", person.Surname, ( rsize_t )100);
^^^^^^^^
这允许跳过输入缓冲区中前导的白色 space 字符。
注意你正在做的改变条件或for循环
for (i = 0; i < n; i++) {
//...
if (r == 1)
n = n + 1;
}
使代码不清楚。您可以使用 do-while 循环代替 for 循环。
您的代码中存在多个问题:
你使用了所谓的secure函数
fopen_s
、scanf_s
等等,但是你没有检查return 值来检测无效输入。您应该改用标准函数,传递适当的参数并检查 return 值。using
scanf_s
实际上是不可移植的:C 标准附件 K 中定义的scanf_s
函数要求指针后的长度参数具有size_t
类型,而 Microsoft 库中具有相同名称的函数使用类型UINT
,它在其 Windows OS 的 64 位版本上具有不同的表示形式。 Embrace, enhance and extinguish 策略的经典案例。在标准 C 中,应该写成:scanf_s("%s", person.Name, (size_t)100)
或更好:scanf_s("%s", person.Name, sizeof person.Name)
无需使用
"w+"
打开输出文件进行更新,只需使用"w"
.您将流指针倒回文件开头并覆盖文件开头的条目数。只要您的条目少于 10 个,此方法就有效,但除此之外,该数字的位数更多,因此文件中的某些字符将被损坏。您可以使用带填充的格式,例如
"%6d\n"
,这样可以无风险地容纳多达 100 万条记录。"%[^\n]s"
不是正确的scanf
格式:您应该只写"%[^\n]"
或更好的" %99[^\n]"
以跳过初始白色 space 并将输入限制为 99 个字符。
这是修改后的版本:
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Staff {
char Surname[100];
char Name[100];
int age;
char spec[100];
int id;
};
void write(void);
void leggi(void);
void trova(void);
int main() {
write();
}
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
void write(void) {
int n = 0;
int r;
FILE *fp = fopen("index.txt", "w");
if (fp == NULL) {
fprintf("Failed to open file index.txt: %s\n",
strerror(errno));
exit(1);
}
fprintf(fp, "%6d\n", n);
for (;;) {
struct Staff person = { 0 };
printf("Surname:\n");
if (scanf(" %99[^\n]", person.Surname) != 1)
break;
flush_input();
fprintf(fp, "%s\t\t", person.Surname);
//loop just get over the name part
printf("Name:\n"); //after the first loop
scanf(" %99[^\n]", person.Name);
flush_input();
fprintf(fp, "%s\t", person.Name);
printf("Age:\n");
scanf("%d", &person.age);
flush_input();
fprintf(fp, "%d\t", person.age);
printf("Specialization\n");
scanf(" %99[^\n]", person.spec, 100);
flush_input();
fprintf(fp, "%s\n", person.spec);
n++;
printf("Want to enter another? 1=yes 0=no...\n");
if (scanf("%d", &r) != 1 || r != 1) {
flush_input();
break;
}
flush_input();
}
rewind(fp);
// update the entry count on 6 characters
fprintf(fp, "%6d\n", n);
fclose(fp);
}