提问人:Ghimire Suraj 提问时间:1/7/2023 更新时间:1/8/2023 访问量:45
“SER_”或“_”字符出现在 C 中(字符串)输出的末尾
'SER_' or '_' character appearing in end of (string)output in c
问:
我正在尝试将每个单词打印在给定句子的一行中。它工作得很好,但行尾会出现一个“_”。请帮我写它,也请适当地写它。
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
char *s,i,check=0;
s = malloc(1024 * sizeof(char));
scanf("%[^\n]", s);
s = realloc(s, strlen(s) + 1);
for(i=0;i<1024;i++ ||check<=2)
{
if(*(s+i)!=' ')
{
printf("%c",*(s+i));
check=0;
}
else
{
printf("\n");
check++;
}
// fflush(stdin);
}
return 0;
}
输出: DKF FJA FJLAK D DKF公司 FJA公司 菲拉克 d SER_
输出2: -for(i=0;我<20;我++ ||检查<=2)- 你好,我是 suraj Ghimire 你好 我 是 苏拉杰 吉
答:
我不确定你的代码是否像你说的那样工作..
- 的类型不是 ,所以它应该是 int。
i
char *
- 在处理输入字符串时,不考虑 NULL 终止字符,这会导致大量垃圾打印。
- 您不会释放分配的内存。
我建议这个稍微修改的版本:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
char *s, *p;
/* Allocate a new string and verify the allocation has succeeded. */
s = malloc(1024 * sizeof(char));
if (!s) {
printf("malloc failed\n");
return 1;
}
/* Read from user. */
scanf("%[^\n]", s);
/* Work on a copy of `s` (must simpler and faster than a indexed access). */
p = s;
while (*p) {
if (*p != ' ') {
printf("%c",*p);
}else{
printf("\n");
}
p++;
}
free(s);
return 0;
}
输出示例:
$ ./a.out
abc def gh i j kmlm opqrst
abc
def
gh
i
j
kmlm
opqrst
编辑:根据 OP 的要求,有关 NULL 终止字符的更多详细信息。
按照惯例,字符串(字符数组)以特定字符结尾,我们称之为 NULL 终止字符。此字符是并标记字符串数据的末尾。0
在您的示例中,存储字符串的缓冲区在 RAM 中动态分配。如果不检查字符串的 NULL 终止字符,则会继续处理数据,就好像它是字符串的一部分一样(但事实并非如此)。
超出此字符后,您可以访问以下内存数据(这是程序RAM数据的一部分)。由于这些数据可以是任何内容(范围从 0 到 255),因此打印它们可能会导致“乱码”,因为它们可能无法打印,并且绝对与您的字符串不一致。
在“最佳”情况下,程序会因“分段错误”而停止,因为您正在访问不允许访问的内存区域。在“最坏”的情况下,你会在崩溃之前打印很多东西。
这通常称为数据泄漏(无论是 RAM 还是 ROM),因为它会暴露程序的内部数据。在您的示例的特定情况下,没有敏感数据。但!想象一下,您泄露了存储在程序中的密码或私钥。这可能是一个严重的安全问题!
您的代码存在几个问题。
首先,您需要检查循环是否不超过字符串的边界。for
您的循环始终设置为 因为逻辑 OR 运算符的优先级高于逗号运算符。因此,循环将始终运行,除非它停止for
true
||
break
最后,在达到值 2 后,u 永远不会重置为 0。check
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char *s,i,check=0;
s = malloc(1024 * sizeof(char));
scanf("%[^\n]", s);
s = realloc(s, strlen(s) + 1);
for(i=0; i<strlen(s); i++) {
if(*(s+i) != ' ') {
printf("%c",*(s+i));
check=0;
} else {
printf("\n");
check++;
if (check > 2) break;
}
}
return 0;
}
输出:
Hello, this is a test
Hello,
this
is
a
test
评论
for(i=0;i<1024;i++ ||check<=2)
有两个问题。一个是字符串的长度并不总是 1024,因此在打印字符串之前确定字符串的长度可能会很好。另一个是 ,它必须放入 for 循环的第二部分,因此将对测试进行评估。另外,最好计算一次字符串的长度。所以我将字符串的长度存储在 .check<=2
len
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *s, i, check = 0;
s = malloc(1024 * sizeof(char));
scanf("%[^\n]", s);
s = realloc(s, strlen(s) + 1);
size_t len = strlen(s);
for (i = 0; i < len || check <= 2; i++) {
if (*(s + i) != ' ') {
printf("%c", *(s + i));
check = 0;
} else {
printf("\n");
check++;
}
// fflush(stdin);
}
return 0;
}
评论