剥离换行符非常棘手
Stripping newline is being very tricky
看起来 scanf() 正在读取前一个 '\n'。我正在尝试将连接的字符串放在一行中。如何去掉第二个字符串开头的“\n”。
这是一个c程序。
我猜我必须在读入下一行之前以某种方式刷新缓冲区。但我不知道如何做到这一点而不会出错。
顺便说一句,我不能在这里使用 cin.get() 或其他标准 cin/cout 操作。我也不能使用标准字符串操作,因为我只使用 c 字符串和 strings.h,而不是字符串。
来自标准输入的输入是:
12
4.0
Spot run!
int main() {
int i = 4;
double d = 4.0;
char s[] = "See ";
int isum;
int MAX_SIZE = 256;
double dsum;
char s2[MAX_SIZE];
scanf("%i",&isum);
scanf("%lf",&dsum); // Hope to clear out the newline from reading
// in the double value. Or any other newline
// before the next scarf(), but haven't figured
// how.
scanf("%79c", s2);
isum += i;
printf("%d \n",isum);
dsum += d;
printf("%.1f \n",dsum);
char newchar[MAX_SIZE];
strcpy(newchar,s);
newchar[strcspn(newchar,"\n")]='[=10=]';
s2[strcspn(s2,"\n")] = 't'; //To test where newline is in second string.
strcat(newchar,s2);
printf("%s",newchar);
return 0;
我的输出是:
16
8.0
See
tSpot run!
//<--注意 Spot 前面的 't'!!!
根据要求。
关于 scanf()
及其相关函数的行为有很多问题,它们是标准 C 库中一些最微妙和最复杂的函数。当下一个字符不是数字的一部分时,诸如 %lf
之类的转换规范将停止读取 - 让该字符由下一个转换规范处理。请注意 %c
(连同 %[…]
扫描集和 %n
)不要跳过前导白色 space;所有其他转换规范都会跳过前导白色 space。如果您不希望数字输入留下换行符,请使用 " %79c"
跳过任何白色 space。格式字符串中的空格会跳过零个或多个白色 space 字符,包括空格、制表符和换行符。
就目前而言,"%79c"
从 4.0
之后读取换行符,'Spot run!
' 中的字符包括其后的换行符,并停止读取假设然后输入到达 EOF。
你不应该在 See
之后换行。 s2[strcspn(s2,"\n")] = 't';
写的t
覆盖了s2
的第一个字节,是4.0以后的换行。
你有没有意识到这一行:
newchar[strcspn(newchar, "\n")] = '[=10=]';
用空字节覆盖 See
之后的 space 之后的空字节,这是一个无操作。
我经常使用的一项技术是打印包含在一组合适的括号中的输入日期,有时 <<…>>
有时 […]
,具体取决于心血来潮或可能的内容。例如:
#include <stdio.h>
#include <string.h>
int main(void)
{
int i = 4;
double d = 4.0;
char s[] = "See ";
int isum;
int MAX_SIZE = 256;
double dsum;
char s2[MAX_SIZE] = ""; // See comments.
scanf("%i", &isum);
scanf("%lf", &dsum);
scanf("%79c", s2);
printf("s2 = [%s]\n", s2);
isum += i;
printf("%d\n", isum);
dsum += d;
printf("%.1f\n", dsum);
char newchar[MAX_SIZE];
strcpy(newchar, s);
newchar[strcspn(newchar, "\n")]='[=11=]';
s2[strcspn(s2, "\n")] = 't';
strcat(newchar, s2);
printf("%s", newchar);
return 0;
}
正如Cool Guy in his 所指出的,重要的是要记住%c
不添加空字节(它只需要存储一个字符);同样,%79c
不会在末尾添加空字节。因此,将 s2
初始化为 'all bytes zero' 是必要的,以防止在连接到 newchar
时出现未定义的行为。或者你必须使用 %n
的精细技术(可能使用两次)来找出有多少字节被读入 s2
以便你可以在事件发生后 null 终止它。
这个变体的输出是:
s2 = [
Spot run!
]
16
8.0
See tSpot run!
所以输入后s2
的开头和结尾各有一个换行符
看起来 scanf() 正在读取前一个 '\n'。我正在尝试将连接的字符串放在一行中。如何去掉第二个字符串开头的“\n”。
这是一个c程序。
我猜我必须在读入下一行之前以某种方式刷新缓冲区。但我不知道如何做到这一点而不会出错。
顺便说一句,我不能在这里使用 cin.get() 或其他标准 cin/cout 操作。我也不能使用标准字符串操作,因为我只使用 c 字符串和 strings.h,而不是字符串。
来自标准输入的输入是:
12
4.0
Spot run!
int main() {
int i = 4;
double d = 4.0;
char s[] = "See ";
int isum;
int MAX_SIZE = 256;
double dsum;
char s2[MAX_SIZE];
scanf("%i",&isum);
scanf("%lf",&dsum); // Hope to clear out the newline from reading
// in the double value. Or any other newline
// before the next scarf(), but haven't figured
// how.
scanf("%79c", s2);
isum += i;
printf("%d \n",isum);
dsum += d;
printf("%.1f \n",dsum);
char newchar[MAX_SIZE];
strcpy(newchar,s);
newchar[strcspn(newchar,"\n")]='[=10=]';
s2[strcspn(s2,"\n")] = 't'; //To test where newline is in second string.
strcat(newchar,s2);
printf("%s",newchar);
return 0;
我的输出是:
16
8.0
See
tSpot run!
//<--注意 Spot 前面的 't'!!!
根据要求。
关于 scanf()
及其相关函数的行为有很多问题,它们是标准 C 库中一些最微妙和最复杂的函数。当下一个字符不是数字的一部分时,诸如 %lf
之类的转换规范将停止读取 - 让该字符由下一个转换规范处理。请注意 %c
(连同 %[…]
扫描集和 %n
)不要跳过前导白色 space;所有其他转换规范都会跳过前导白色 space。如果您不希望数字输入留下换行符,请使用 " %79c"
跳过任何白色 space。格式字符串中的空格会跳过零个或多个白色 space 字符,包括空格、制表符和换行符。
就目前而言,"%79c"
从 4.0
之后读取换行符,'Spot run!
' 中的字符包括其后的换行符,并停止读取假设然后输入到达 EOF。
你不应该在 See
之后换行。 s2[strcspn(s2,"\n")] = 't';
写的t
覆盖了s2
的第一个字节,是4.0以后的换行。
你有没有意识到这一行:
newchar[strcspn(newchar, "\n")] = '[=10=]';
用空字节覆盖 See
之后的 space 之后的空字节,这是一个无操作。
我经常使用的一项技术是打印包含在一组合适的括号中的输入日期,有时 <<…>>
有时 […]
,具体取决于心血来潮或可能的内容。例如:
#include <stdio.h>
#include <string.h>
int main(void)
{
int i = 4;
double d = 4.0;
char s[] = "See ";
int isum;
int MAX_SIZE = 256;
double dsum;
char s2[MAX_SIZE] = ""; // See comments.
scanf("%i", &isum);
scanf("%lf", &dsum);
scanf("%79c", s2);
printf("s2 = [%s]\n", s2);
isum += i;
printf("%d\n", isum);
dsum += d;
printf("%.1f\n", dsum);
char newchar[MAX_SIZE];
strcpy(newchar, s);
newchar[strcspn(newchar, "\n")]='[=11=]';
s2[strcspn(s2, "\n")] = 't';
strcat(newchar, s2);
printf("%s", newchar);
return 0;
}
正如Cool Guy in his %c
不添加空字节(它只需要存储一个字符);同样,%79c
不会在末尾添加空字节。因此,将 s2
初始化为 'all bytes zero' 是必要的,以防止在连接到 newchar
时出现未定义的行为。或者你必须使用 %n
的精细技术(可能使用两次)来找出有多少字节被读入 s2
以便你可以在事件发生后 null 终止它。
这个变体的输出是:
s2 = [
Spot run!
]
16
8.0
See tSpot run!
所以输入后s2
的开头和结尾各有一个换行符