'N'字符出现在字符串的末尾

问题描述 投票:1回答:3

我是C的新手,在尝试输入字符串时我正在处理一个问题。更具体地说,当打印字符串时,字符“N”出现在它的末尾,因此,我无法测量确切的字符数。这是我的代码:

int main()
{
    int j = 0;
    char c[15];
    printf("Give surname: ");
    scanf(" %s", c);
    for (int i = 0; i<sizeof(c) / sizeof(c[1]); i++)
    {
        if (isalpha(c[i]))
        {
            printf("%c ", c[i]);
            j++;
        }
    }
    printf("\nNumber of characters: %d", j);

    return 0;
}

例如:如果输入是“john”,那么我得到以下输出:

enter image description here

我究竟做错了什么?

c string scanf
3个回答
2
投票

请尝试使用strlen()函数。它检查实际字符串末尾的空终止字符(与完整数组相反,完整数组可能包含空终止字符后的乱码字符)。

int length = strlen(c);
for (int i = 0; i < length; i++){

记住#include <string.h>

在这里看到它:https://repl.it/repls/SugaryUnfoldedCleaninstall

如果您想知道为什么需要依赖函数来执行此操作,请查看the source of strlen()。编写这样一个表现良好且在所有情况下都正确的函数比它看起来更难。

进一步阅读 How to iterate over a string in C


3
投票

那是因为你在字符数组上使用sizeof运算符,它比实际字符串长。您可以使用strlen中的string.h,如上所述,或者简单地迭代chars直到\0,就像那样:

char * p = c;
while(*p++)
    if (isalpha(*p))
        printf("%c ", *p);

如果你对字符数感兴趣,你可以减去指针。


3
投票

你的循环限制是错误的。它会导致您评估不确定的数据。事情特别错误:

  • 没有检查scanf的成功
  • 不指定长度受限的格式字符串以避免溢出c[]数组。
  • 如上所述,迭代整个数组而不仅仅是您假设的数据已成功读取。

所有这些都可以修复,其中一些是微不足道的。

  • 检查scanf返回1
  • 由于你的c数组是15个字符,并且空格必须考虑终止nullchar,所以使用%14s作为格式字符串
  • 使用strlen作为你的限制(以某种方式,将它保存到临时或直接在条件子句中)或使用指针。

关于最后一项,我更喜欢后者,因为你只扫描一次字符串。 strlen将扫描字符串以找到终结符,从而计算长度并返回它。然后在迭代期间再次扫描它。您可以通过简单地不使用它来消除strlen扫描,而是使用指针代替,并在发现终结符时停止扫描。

重写,这是结果:

#include <stdio.h>
#include <ctype.h>

int main()
{
    char c[15];
    int j = 0;

    printf("Give surname: ");
    if (scanf("%14s", c) == 1)
    {
        for (const char *p = c; *p; ++p)
        {
            if (isalpha(*p))
            {
                printf("%c ", *p);
                ++j;
            }
        }

        printf("\nNumber of characters: %d", j);
    }

    return 0;
}

输入

123john456

产量

j o h n
Number of characters: 4
© www.soinside.com 2019 - 2024. All rights reserved.