C程序帮助上套管输入的第一个字母

时间:2017-02-08 06:56:37

标签: c

我是初学者编写者并编写了

代码
  

询问用户的姓名

     

检查长度是否> 15,如果是,它将要求用户在重新启动程序时输入更短的名称

     

如果长度有效,则大写输入名称的第一个字母

     

显示类似"嗨名称"

然而,无论我输入什么,程序都会一直存在。这是我做的:

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

int main(void)
{
    char str_name[15];

    printf("Please enter your first name to begin: ");
    scanf_s("%14s", str_name, _countof(str_name));
    getchar();

    if (strlen(str_name) > 15)
    {
        printf("The entered name is too long, please restart the program and try again.");
        getchar();
        exit(0);
    }
    else
    {
        str_name[0] = toupper(str_name[0]);

        printf("Hi %s.\n", str_name);
        getchar();
    }

    return 0;
}

4 个答案:

答案 0 :(得分:1)

您只需使用fgets()即可读取输入缓冲区。

  

"从指定的流中读取一行并将其存储在 str 指向的缓冲区中。当读取char *fgets(char *str, int n, FILE *stream)个字符,读取换行符或达到n-1时,它会停止。

有关EOF的一些注意事项:

  • 出错时返回fgets()
  • 在缓冲区末尾添加NULL个字符。可以替换为\n
  • 缓冲区必须是指向字符数组的指针。分配在堆栈或堆上。
  • \0stdin个对象中读取。

以下是一些示例代码:

FILE

答案 1 :(得分:0)

您的代码中存在以下几个问题:

  • 缓冲区大小太短:scanf()不会将超过14个字节读入str_name,因此无法测试用户是否输入了超过15个字符的名称。

  • toupper()不应该被赋予char参数,因为它仅针对类型unsigned char和特殊值EOF的值进行定义。将char投射为unsigned char

  • 您在终端窗口关闭之前暂停的尝试在Windows的长名称上失败,因为用户输入的额外字符在scanf_s()之后仍然未决。 getchar()读取一个并立即返回,程序退出并终止窗口关闭。打开终端窗口并手动运行程序,使其不会自动关闭。使用此方法,您可以删除getchar()并使程序更具可移植性。

以下是更正后的版本:

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

int main(void) {
    char str_name[17];

    printf("Please enter your first name to begin: ");
    if (scanf_s("%16s", str_name, sizeof(str_name))) {
        printf("Premature end of file.\n");
        return 1;
    }
    if (strlen(str_name) > 15) {
        printf("The entered name is too long, please restart the program and try again.");
        return 1;
    }
    str_name[0] = toupper((unsigned char)str_name[0]);
    printf("Hi %s\n", str_name);
    return 0;
}

答案 2 :(得分:-1)

问题是:

    char Name[1];  // Declare a single element array.
    Name[0] = toupper(str_name[0]); // Set it to the upper-case first letter.

    // Try and print the nul-terminated string in Name - but there is no
    // trailing zero (and the rest of the name is missing).
    printf("Hi %s.\n", Name);

您需要的是:

    str_name[0] = toupper(str_name[0]);
    printf("Hi %s.\n", str_name);

另一个问题是str_name[0]char值,而char可能会被签名。例如,如果您使用的是Windows-1252,则Ä为196,或者作为签名字符,-60。 toupper需要int必须为正¹。当-60作为signed char转换为int时,您将得到-60,并且超出范围错误。你需要把它写成:

    str_name[0] = toupper((unsigned char)str_name[0]);
    printf("Hi %s.\n", str_name);

(对不起。)

¹Chrqlie指出要求实际上是参数必须是unsigned char的值之一(根据定义 - 非负)或EOF(是< / em>否定)“

答案 3 :(得分:-1)

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

int main(void)
{
    char str_name[16] = {0};
    size_t len = 0;
    int ch;

    printf("Please enter your first name to begin: ");

    while ((EOF != (ch = fgetc(stdin))) && (ch != '\n') && (len<sizeof(str_name)))
    {
        if (isalpha(ch))
        {
            str_name[len++] = ch;
        }
    }

    if (len==sizeof(str_name))
    {
        fprintf(stderr, "Name too long\n");
    }
    else
    {
        str_name[len] = '\0';
        printf ("Hi %c%s.\n", toupper(str_name[0]), &str_name[1]);
    }

    return 0;
}

如您所见,我更改了输入抓取功能。要检查输入str len,您应该读取每字节的字节数,而不是整个字符串:fgetc执行此操作。使用格式说明符如%14s的scanf,它将返回一个修剪后的字符串,并且您无法警告用户有太长的名称。

另一点是检查插入的字符是字母而不是其他类型的字符:isalpha完成工作。

此外,c-string由chars加上一个空终止符('\ 0',0x00)组成,因此:15个字符串需要一个16字节的数组。

最后,您编写的第一个字母大写的代码是完全错误的:您传递的是打印1个char数组而不是c字符串。我的解决方案是其中之一。