出现在c中(字符串)输出末尾的“SER_”或“_”字符

1rhkuytd  于 2023-01-08  发布在  其他
关注(0)|答案(3)|浏览(100)

我试图在一个给定的句子的单行打印每个单词。它工作得很好,但一个'_'出现在行尾。请帮助我,也适当manar写它。

#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 fjlak d SER
输出2:-对于(i=0; i〈20;i++|| check〈=2)-你好我是苏拉杰·吉米尔你好我是苏拉杰·吉

ddrv8njm

ddrv8njm1#

我不确定你的代码是否像你说的那样有效。

  • i的类型不是char *,所以应该是int。
  • 处理输入字符串时不考虑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,标志着字符串数据的结束。
在你的例子中,存储字符串的缓冲区是动态分配的,如果你不检查字符串的NULL终止字符,那么你就继续处理数据,就好像它是字符串的一部分一样(实际上它不是)。
超过这个字符会使你访问以下的内存数据(这是你的程序RAM数据的一部分)。由于这些数据可以是任何值(从0到255),打印它们可能会导致"乱码",因为它们可能不能打印,而且肯定与你的字符串不一致。
在"最好"的情况下,程序会因为"分段错误"而停止,因为你正在访问一个你不允许访问的内存区域。在"最坏"的情况下,你在崩溃前打印了很多东西。
这通常被称为数据泄漏(无论是RAM还是ROM),因为它暴露了程序的内部数据。在您的示例的特定情况下,没有敏感数据。但是!想象一下您泄漏了存储在程序中的密码或私钥。这可能是一个严重的安全问题!

kq0g1dla

kq0g1dla2#

你的代码有几个问题。
首先,您需要检查for循环是否超出字符串的边界。
您的for循环始终设置为true,因为逻辑OR运算符||的优先级高于逗号运算符。因此,循环将始终运行,除非使用break停止
最后,check在达到值2后永远不会重置为0。

#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
20jt8wwn

20jt8wwn3#

for(i=0;i<1024;i++ ||check<=2)

这里有两个问题。一个是字符串的长度不会总是1024,所以在打印字符串之前确定字符串的长度可能是好的。另一个是check<=2,它必须放在for循环的第二部分,所以测试将被评估。而且最好一次计算字符串的长度。所以我将字符串的长度存储在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;
}

相关问题